[Zope-dev] Re: zope.sqlalchemy, integration ideas

Michael Bayer mike_mp at zzzcomputing.com
Fri May 30 15:11:35 EDT 2008


On May 30, 2008, at 9:44 AM, Martijn Faassen wrote:

> Hey,
>
> Michael Bayer wrote:
>
> [snip discussion on BoundMetadata I don't comprehend yet but  
> probably should :)]
>
>> As far as ScopedSession, it's really just a thread local variable.   
>> Like any global threadlocal, you can stick whatever you want on it  
>> at the start of a request, and tear it down at the end.
>
> Is it really needed to set things up at the start and the request  
> and tear things down on the end, or can a session be retained  
> between requests? I.e. is the intent to recreate a Session class  
> each time a request is issued?

in the 0.4 series, the Session is "sticky" in that whatever is in it  
retains the state that was last loaded - 0.4 does not go back to the  
database to re-fetch the state of an object unless its explicitly told  
to do so.   When an HTTP request ends, assuming all objects in the  
session are marked as "clean", they're weakly referenced and will fall  
out of scope assuming those objects were only referenced by the  
request.  So in that sense, you can just leave the Session alone and  
it'll work just fine for the next request...but any pending changes in  
the Session that weren't flushed for some reason would get carried  
over, as well as anything that might be strongly referenced  
elsewhere.  So we always recommended in 0.4 to at least issue a  
session.clear() at the end of a request to just empty it out (but you  
can still reuse that session).  Other options included  
scopedsession.remove() which tears the whole session down, the  
advantage there being that the new request could configure the next  
session differently (as in, binding it to something else).

in 0.5, Session has been changed to be less reluctant to go and "re- 
fetch" data (which is contrary to the particular background I came  
from, but since then I've learned to see a broader scope of use  
cases).   In 0.5, after a commit() or rollback(), the Session still  
may be holding on to objects, but their state is expired such that it  
will all be re-loaded upon access, and all "pending" and "deleted"  
states are reverted.  So 0.5's Session, when configured in the default  
way, makes it very hard to get at "stale" state, so in that sense you  
can just re-use a session wihtout worrying much about what may have  
been left over.


>> Then again it's also reasonable that you might want to have  
>> individual ScopedSessions for each application instance within a  
>> multi-app process, that way the burden of setting up/tearing down  
>> is reduced or removed.
>
> This indicates to me is possible to retain a Session object between  
> two requests? I.e. it's a worthwhile goal to reduce the amount of  
> Session configuration going on, right?

Its not a strong argument either way to reuse a session or just make a  
new one on each request.  In 0.4, making a brand new session on each  
request does have a "cleaner" feel to it since theres no chance of any  
state left hanging around.  Its not an expensive operation.

>> A single ScopedSession for a multi-app process is like a one- 
>> dimensional approach where both current thread and current app are  
>> identified by the current "get()" of the registry; a collection of  
>> ScopedSessions is more like a two-dimensional approach where the  
>> first level of registry (i.e. which ScopedSession do I choose)  
>> distinguishes between app instance, and the second level (i.e. what  
>> Session is bound to this thread ID) distinguishes between threads.
>> All of that said I think it can work either way but I think the  
>> latter approach might have the explicitness you're looking for.
>
> I'm trying to understand why you think so. I am looking for a way to  
> let developers use SQLAlchemy in a straightforward way. They should  
> be able to import 'Session', instantiate session in their app, and  
> everything works as expected. The framework takes care of making you  
> get the appropriately configured Session.

they can in fact do this without any issue.    The question is, when  
someone writes the call "s = Session()" three times within one  
request, do you want each "s" to all reference the *same* set of  
objects ?  that was the issue scoped_session() was meant to solve.   
Configuration is easy since you just configure a "Session" callable  
for that application.

But you guys have this issue of "multiple applications in the same  
process" at play, which each talk to a different database.  So thats  
where a decision has to be made how to deal with that complexity,  
either configure engine on one scoped_session per request, or  
configure multiple scoped_sessions, one per engine.   The latter  
approach seems "easier" to me since you don't actually have to do  
anything on a per-request basis assuming 0.5 usage.   Neither of these  
make any difference to the end user who sees the exact same usage  
pattern.

> (I'd still absolutely like to avoid passing in context explicitly  
> each time you need a session; it puts unnecessary burden on the  
> developer and promises to make multi-application interactions easier  
> while it actually doesn't do so)

so one scoped_session() per app instance/engine seems like the easiest  
way to do this.



More information about the Zope-Dev mailing list