I don't get it, but this code doesn't call after_flush/before_flush/aft开发者_如何学编程er_flush_postexec
# -*- coding: utf-8 -*-
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.orm.interfaces import SessionExtension
class AfterFlushExtension(SessionExtension):
def before_commit(self, session):
print "> before_commit"
def after_commit(self, session):
print "> after_commit"
def before_flush(self, session, flush_context, instances):
print '> before_flush'
def after_flush(self, session, flush_context):
print '> after_flush'
def after_flush_postexec(self, session, flush_context):
print '> after_flush_postexec'
session = scoped_session(sessionmaker(extension=AfterFlushExtension()))
session.flush()
session.commit()
And a result:
$ python ~/Dropbox/playground/python/sqlalchemy_hook_test/main.py
> before_commit
> after_commit
Michael Bayer answered on SQLAlchemy's mailing list https://groups.google.com/d/msg/sqlalchemy/GrMZGtJ-yc8/mCviGB6g9HYJ :
The flush events only fire off if there's actually something to be flushed. It would be inefficient for the events to be emitted for every flush() as flush is in fact called a great number of times, on every query, assuming autoflush enabled. For this reason a flush() with a session that has no change events of any kind quickly checks some flags and returns.
Think of before_flush() really being called before_flush_on_pending_changes() if that helps.
I'll check the docstrings to see if any clarification is needed.
Thanks, Michael
精彩评论