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:
finally:
if session.has_uncommitted_changes():
raise SessionLeftUnclean()
Any and all help gratefully appreciated!
Regards,
Tom