On Oct 10, 2013, at 8:57 PM, Iain Duncan <iainduncanli...@gmail.com> wrote:
> Seems like there are some variety of opinion on some stuff on the pyramid > list so I thought I'd come straight to the source. In Pyramid, I can attach a > server wide shared object to the registry which is created on server startup, > and I can specify a factory for making requests that creates the request > object, available as a local argument (*not* a thread local request import) > to all code. In the request object I can also add an end-of-life callback. > > I've been using SQLAlchemy by: > > - creating the engine and sessionmaker at startup time, stashing in the ZCA > registry > - calling the session maker at the beginning of the request lifecycle and > then creating the session for that request and attaching to the request. > - doing a cleanup at end of request > > According to my (possibly flawed) understanding of the SA docs, this should > mean I do not need to use a scoped session maker. that is correct. > The session object never gets imported as a magic global thread local thing, > it's always explicitly passed in as an arg. you can also link the two things together like this, not that you'd need to: from pyramid.threadlocal import get_current_request Session = scoped_session(sessionmaker(), scopefunc=get_current_request) now you're only using Pyramid's thread local voodoo, none in SQLAlchemy. > Am I correct in this? Is there any advantage in using a scoped session anyway? I find plenty. I'm usually concerned about code that needs to run outside the context of a web request, like background jobs and utilities - this code still makes full use of the web app's model and all, just not the "request". So without Pyramid's hook for session creation, someone else has to establish the new Session. ScopedSession is nice because nobody has to tag themselves as the "creator" of the Session, it just creates the new Session as soon as someone starts using it. Also having to pass a session around to all methods and functions that aren't web-request-aware can become burdensome. My app over here actually has three different sessions for different use cases, so I guess if I weren't using scoped sessions I'd need to create some more substantial context object that I pass around to all these methods which has all three sessions, but then I'd need to reconcile that context object with Pyramid's request also. Or perhaps, you can just make Pyramid's "request" the context itself and when you're running in a non-web context just use DummyRequest or something, but doesn't that seem strange/weird also? Model objects that have nothing to do with web requests all have to become hardcoded to the concept of a "request", that seems no less distasteful than thread locals to me. With a scoped session, none of these decisions even need to be made, you don't have to pass anything around to your model, the model has a place to get its context for database connectivity just like it has a place to get context for anything else it needs. There's no downside to scoped sessions that I've observed and the Pyramid community's aversion to thread local "voodoo" IMHO is slightly misplaced. Thread locals are, like so many other things, easy to misuse, particularly when random bits of code use them to communicate state and such. But having a few well-located and globally accessible registries that are specific to your application, not a problem at all. I see no evidence for Pyramid's assertion that they decrease testability, it's standard practice to patch well-known globals for testing, and in fact "mock.patch" is part of the Python standard library now.
signature.asc
Description: Message signed with OpenPGP using GPGMail