Events 如何添加在sqlalchemy中提交事务后仅触发一次的事件处理程序
我正在使用sqlalchemy编写一些函数。这些函数称为内部事务,如:Events 如何添加在sqlalchemy中提交事务后仅触发一次的事件处理程序,events,transactions,sqlalchemy,Events,Transactions,Sqlalchemy,我正在使用sqlalchemy编写一些函数。这些函数称为内部事务,如: def create_order(session, *arg, **kw): # create order object order = Order(xxxx=xxx) session.add(order) # order extra operations order_extra_data = OrderExtraData(yyyy=yyyy) session.add(ord
def create_order(session, *arg, **kw):
# create order object
order = Order(xxxx=xxx)
session.add(order)
# order extra operations
order_extra_data = OrderExtraData(yyyy=yyyy)
session.add(order_extra_data)
# more operations
....
# email should be sent to the order's owner
订单创建成功后,应向用户发送电子邮件。但是在create_order的末尾,事务尚未提交,可能会被稍后的代码中止。所以这个函数不应该直接发送邮件。相反,它应该注册一个一次性事件处理程序,该处理程序仅在会话提交后触发(如果事务是回滚或关闭的,则不触发并清除)。如何实现此功能?您可以使用
once=True来侦听会话事件:
def create_order(session, ...):
...
@event.listens_for(session, "after_commit", once=True)
def _send_email_after_commit(session):
send_email()
如果您希望回滚并重用会话(并且不希望侦听器在回滚后启动),您还需要在发生回滚时删除事件:
def create_order(session, ...):
...
@event.listens_for(session, "after_commit", once=True)
def _send_email_after_commit(session):
send_email()
@event.listens_for(session, "after_soft_rollback", once=True)
def _remove_event_listener_on_rollback(session, prev_transaction):
event.remove(session, "after_commit", _send_email_after_commit)
好的thx,我也在读关于事件的文档。是否保证在提交后和软回滚后都会被调用(如果直接调用session.close(),是否会触发软回滚后?)。为什么要使用after_soft_rollback而不是after_rollback?@jayven我相当肯定,一个事务可以保证提交(提交后
)或回滚(提交后
)。我不确定的唯一情况是交易是否尚未启动,但这几乎从未发生过<代码>会话。关闭
也无关紧要,因为在会话关闭后,您将无法重用该会话(并且您创建的任何新会话都不会将侦听器附加到过去的其他会话)。在软回滚后使用,因为它是对应于会话的事件。回滚()
after_rollback
对应于SQLrollback
。Thx对于您的解释,这对我帮助很大。