On Mar 28, 2010, at 10:26 AM, Peteris Krumins wrote:

> Hi all,
> 
> Can anyone explain to me how to correctly create sessions in web
> applications?
> 
> The documentation gives an example with a scoped_session:
> 
>    from sqlalchemy.orm import scoped_session, sessionmaker
>    Session = scoped_session(sessionmaker())
> 
> Okay, I should wrap the "thing" returned by sessionmaker() in
> scoped_session(). But do I later still have to construct Session() by
> doing this:
> 
>    session = Session()
> 
> I did some experiments and I don't get it.
> 
> Here is the code I tried:
> 
>>>> from app.models import Page
>>>> 
>>>> Session = sessionmaker(bind=engine, autoflush=True,
> autocommit=False)
>>>> session = scoped_session(Session)
>>>> 
>>>> session
>    <sqlalchemy.orm.scoping.ScopedSession object at 0x848eb8c>
>>>> session()
>    <sqlalchemy.orm.session.Session object at 0x83fe08c>
>>>> session.query(Page).count()
>    211L
>>>> session().query(Page).count()
>    211L
> 
> Both work identically, but I don't understand the difference. Can
> anyone explain it please?
> 
> Also when do I have to call remove() method that is mentioned in
> documentation?

ScopedSession is a class that implements __call__().    An instance of 
ScopedSession then maintains a reference to a thread local object, which in 
turn references individual Session objects.   So if "ss" is a ScopedSession 
instance, calling ss() (i.e. its __call__() method) returns the current 
thread's Session.   In this way ScopedSession mimics a "constructor", and an 
existing application which says "sess = Session(); sess.query(Foo)" can 
transparently be made to use a thread-scoped session by changing the meaning of 
the identifier "Session".

The second part of the story is that people found it tedious to say sess = 
Session(); sess.query(Foo) all the time to perform an operation on the current 
thread's session, so a __getattr__()-like scheme was added  which compresses 
those two steps into one, meaning <some_scoped_session>.<some_Session_method>() 
equates to "sess = Session(); return sess.<some_Session_method>()".  But what 
this also means is, like the case of __call__(), an application which currently 
uses a single global Session to do everything, i.e. "session.query(Foo)" 
throughout, can also transparently be made to use a thread-scoped session by 
changing the meaning of the identifier "session".



> 
> 
> Thanks,
> Peteris Krumins
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to