有没有办法在 SQLAlchemy ORM 中将对象显式标记为干净?
这部分与之前关于 bulk update strategies 的问题有关.
我想在 before_flush
事件监听器中将一堆对象标记为实际上不需要刷新。这是因为它们通过其他方式手动与数据库同步。
我尝试了下面的策略,但它导致对象从 session 中删除,这可能会在以后发生延迟加载时导致问题。
@event.listens_for(SignallingSession, 'before_flush')
def before_flush(session, flush_context, instances):
ledgers = []
if session.dirty:
for elem in session.dirty:
if ( session.is_modified(elem, include_collections=False) ):
if isinstance(elem, Wallet):
session.expunge(elem) # causes problems later
ledgers.append(Ledger(id=elem.id, amount=elem.balance))
if ledgers:
session.bulk_save_objects(ledgers)
session.execute('UPDATE wallet w JOIN ledger l on w.id = l.id SET w.balance = l.amount')
session.execute('TRUNCATE ledger')
我想做这样的事情:
session.dirty.remove(MyObject)
但这不起作用,因为 session.dirty
是计算属性,而不是常规属性。我一直在深入研究检测代码,但看不出如何欺骗 dirty
列表不包含某些内容。我看到还有一个关于对象状态的 history
也需要处理。
有什么想法吗?如果有任何区别,底层数据库是 MySQL。
-马特
最佳答案
当您在 ORM 之外修改数据库时,您可以使用 set_committed_value()
让 ORM 知道当前的数据库状态。 .
例子:
wallet = session.query(Wallet).filter_by(id=123)
wallet.balance = 0
session.execute("UPDATE wallet SET balance = 0 WHERE id = 123;")
set_committed_value(wallet, "balance", 0)
session.commit() # won't issue additional SQL to update wallet
如果您真的想要将实例标记为不脏,您可以处理 SQLAlchemy 的内部结构:
state = inspect(p)
session.identity_map._modified.discard(state)
state.modified = False
print(p in session.dirty) # False
关于python - 在 SQLAlchemy ORM 中将对象标记为干净,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41879671/