from sqlalchemy import event
from sqlalchemy.orm import Session
@event.listens_for(Session, "after_flush")
def log_flush(session, flush_context):
session.info['flushed'] = True
@event.listens_for(Session, "after_commit")
@event.listens_for(Session, "after_rollback")
def reset_flushed(session):
if 'flushed' in session.info:
del session.info['flushed']
def has_uncommitted_changes(session):
return any(session.new) or any(session.deleted) \
or any([x for x in session.dirty if session.is_modified(x)]) \
or session.info.get('flushed', False)
from sqlalchemy import event
import weakref
transactions_with_flushes = weakref.WeakSet()
@event.listens_for(Session, "after_flush")
def log_transaction(session, flush_context):
for trans in session.transaction._iterate_parents():
transactions_with_flushes.add(trans)
def session_has_pending_commit(session):
return session.transaction in transactions_with_flushes
这是我根据@zzzeek的回答和最新评论提出的解决方案。我已经对它进行了单元测试,它似乎可以很好地处理回滚(会话在发出回滚后是干净的):
会话具有脏属性
会话.dirty
当前检测到更改的持久对象 (现在,每次调用属性时都会动态创建此集合)
sqlalchemy.orm.session.Session.dirty
您正在寻找在会话事务的整个范围内进行的实际刷新的净计数;虽然有一些线索表明是否发生了这种情况(称为“快照”),但这种结构只是为了帮助回滚,而不是强引用。最直接的方法是跟踪“after_flush”事件,因为此事件仅在调用flush时才会发出,并且flush found状态为flush:
编辑:这里有一个更简单的更新版本:
相关问题 更多 >
编程相关推荐