如何检查SQLAlchemy会话是否脏

Gio*_*ani 14 python sqlalchemy

我有一个SQLAlchemy Session对象,想知道它是否脏.我想(比喻)要问的确切问题Session是:"如果此时我发出a commit()或a rollback(),对数据库的影响是否相同?".

理由是:我想询问用户是否想要确认更改.但如果没有变化,我不想问任何问题.当然,我可以监视自己执行的所有操作,Session并决定是否有修改,但由于我的程序结构,这需要一些相关的更改.如果SQLAlchemy已经提供了这个机会,我很乐意利用它.

谢谢大家.

zzz*_*eek 13

您正在寻找在整个会话交易期间进行的实际刷新的净计数; 虽然有一些关于这是否发生的线索(称为"快照"),但这种结构只是为了帮助回滚,而不是强引用.最直接的方法是跟踪"after_flush"事件,因为此事件仅在调用flush时发出,并且flush发现状态为flush:

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
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个更简单的更新版本:

from sqlalchemy import event

@event.listens_for(Session, "after_flush")
def log_transaction(session, flush_context):
    session.info['has_flushed'] = True

def session_has_pending_commit(session):
    return session.info.get('has_flushed', False)
Run Code Online (Sandbox Code Playgroud)

  • 无论如何,这个答案很奇怪.Session最近有一个.Info字典.将"flushed = True"放入after_flush并在after_commit中将其删除.我不知道为什么我要把所有SessionTransaction对象放在字典中. (2认同)