On Oct 9, 2014, at 6:09 AM, Tom Dalton <tom.dal...@fanduel.com> wrote:

> Using SQLAlchemy 0.9.
> 
> I am writing a server, that's running in gevent. As part of the library code, 
> I am trying to write a session context manager that checks if the session has 
> uncommitted changes when it's exited (this situation represents a 
> logic/programming error, as I expect every server 'request' to finish with a 
> committed or rolled back transaction. Each request has its own session but 
> there may be multiple transactions within that request/session.
> 
> Based on the docs for Session and this question at stackoverflow 
> (http://stackoverflow.com/questions/13910576/find-out-how-many-uncommitted-items-are-in-the-session)
>  I wrote a context manager like so:
> 
> @contextmanager
> def checked_scoped_session():
>     session = get_session()
>     try:
>         yield session
>     except:
>         session.rollback()
>         raise
>     finally:
>         if session.new or session.dirty or session.deleted:
>             new = len(session.new)
>             dirty = len(session.dirty)
>             deleted = len(session.deleted)
>             msg = "Session left with ({} new, {} dirty, {} deleted) 
> instances"\
>                 " uncommitted".format(new, dirty, deleted)
>             raise SessionLeftUnclean(msg)
>         session.close()
> 
> While testing, I discovered that session.new, .dirty and .deleted appear to 
> actually be UNFLUSHED instances, and not uncommitted. This is a problem since 
> I am using (and want to keep using) autoflush. I have been reading up on 
> session.transaction, however, it's still not clear to me how I can tell if 
> the transaction has (uncommitted) changes, and this seems to be further 
> complicated by the possibility of sub-transactions.
> 
> Is there an easy way to do what I want? E.g. Ideally I want to do:

Checking .new, .dirty, and .deleted is not a bad idea because they indicate 
activity that has occurred on the session subsequent to the last commit().    
But if these changes have been flushed, then it's "clean", but the transaction 
may not have been committed yet.   Right now the documentation encourages just 
using events (eg. after_begin, after_commit, after_rollback) to track the state 
of the Session regarding connections as you see fit, there's not a public API 
method of checking this.   

If you really want to see if the session is linked to a transaction in 
progress, you could check len(session.transaction._connections), if that's 
nonzero, then there's a DBAPI-level transaction in progress - it means there's 
one or more connections that the Session is linked to.   But you could achieve 
this same information using after_begin as well.


-- 
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/d/optout.

Reply via email to