In Twisted there is a great thing known as `ContextTracker`: > provides a way to pass arbitrary key/value data up and down a call > stack without passing them as parameters to the functions on that call > stack.
In my twisted web app in method `render_GET` I set a `uuid` parameter: call = context.call({"uuid": str(uuid.uuid4())}, self._render, request) and then I call the `_render` method to do the actual work (work with db, render html, etc). I create the `scoped_session` like this: scopefunc = functools.partial(context.get, "uuid") Session = scoped_session(session_factory, scopefunc=scopefunc) Now within any function calls of `_render` I can get session with: Session() and at the end of `_render` I have to do `Session.remove()` to remove the session. It works with my webapp and I think can work for other tasks. This is completely standalone example, show how all it work together. from twisted.internet import reactor, threads from twisted.web.resource import Resource from twisted.web.server import Site, NOT_DONE_YET from twisted.python import context from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy.ext.declarative import declarative_base import uuid import functools engine = create_engine( 'sqlite:///test.sql', connect_args={'check_same_thread': False}, echo=False) session_factory = sessionmaker(bind=engine) scopefunc = functools.partial(context.get, "uuid") Session = scoped_session(session_factory, scopefunc=scopefunc) Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) Base.metadata.create_all(bind=engine) class TestPage(Resource): isLeaf = True def render_GET(self, request): context.call({"uuid": str(uuid.uuid4())}, self._render, request) return NOT_DONE_YET def render_POST(self, request): return self.render_GET(request) def work_with_db(self): user = User(name="TestUser") Session.add(user) Session.commit() return user def _render(self, request): print "session: ", id(Session()) d = threads.deferToThread(self.work_with_db) def success(result): html = "added user with name - %s" % result.name request.write(html.encode('UTF-8')) request.finish() Session.remove() call = functools.partial(context.call, {"uuid": scopefunc()}, success) d.addBoth(call) return d if __name__ == "__main__": reactor.listenTCP(8888, Site(TestPage())) reactor.run() Still I dont know how to make it work with `defer.inLineCallback`, that I use everywhere in my code. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.