尽管在 SQLAlchemy 中引发了自定义异常,但仍提交
Commit despite raising custom exception in SQLAlchemy
我正在尝试在 table 中插入新记录时显示警报。为了传达新数据已被插入,我提出了一个自定义异常。但是,我发现只要引发自定义异常,提交就不会成功完成。是否可以强制它在异常情况下完成,或者是否有更好的替代方法来执行此操作?
@event.listens_for(Session, "after_flush")
def after_flush(session, flush_context):
for instance in session.new:
if hasattr(instance, "on_insert"):
instance.on_insert(session)
如果我不引发自定义异常,则以下是正常提交的
def on_insert(self, session):
# Removed code which utilises the passed in session, as such after_insert event hook is probably not going to be suitable
session.commit() # Leads to ResourceClosedError which rolls back the transaction
raise NewClientError(f"{self.__repr__()}")
#pass
因为上面的on_insert是运行在父事务中,再次执行commit()最终会导致ResourceClosedError回滚父事务。
我通过引发自定义异常作为 after_commit 事件挂钩的一部分来解决这个问题:
https://gist.github.com/letmaik/b296b02e730cd4c469bf
和 How do I get SQLAlchemy objects after commit?
在我的例子中,我刚刚修改了 on_insert 函数来为 after_commit:
注册一个监听器
def on_insert(self, session):
event.listen(session, "after_commit", self.__raise_alert)
这现在会在事务完成后调用 __raise_alert,因此不会导致回滚。
我正在尝试在 table 中插入新记录时显示警报。为了传达新数据已被插入,我提出了一个自定义异常。但是,我发现只要引发自定义异常,提交就不会成功完成。是否可以强制它在异常情况下完成,或者是否有更好的替代方法来执行此操作?
@event.listens_for(Session, "after_flush")
def after_flush(session, flush_context):
for instance in session.new:
if hasattr(instance, "on_insert"):
instance.on_insert(session)
如果我不引发自定义异常,则以下是正常提交的
def on_insert(self, session):
# Removed code which utilises the passed in session, as such after_insert event hook is probably not going to be suitable
session.commit() # Leads to ResourceClosedError which rolls back the transaction
raise NewClientError(f"{self.__repr__()}")
#pass
因为上面的on_insert是运行在父事务中,再次执行commit()最终会导致ResourceClosedError回滚父事务。
我通过引发自定义异常作为 after_commit 事件挂钩的一部分来解决这个问题:
https://gist.github.com/letmaik/b296b02e730cd4c469bf 和 How do I get SQLAlchemy objects after commit?
在我的例子中,我刚刚修改了 on_insert 函数来为 after_commit:
注册一个监听器 def on_insert(self, session):
event.listen(session, "after_commit", self.__raise_alert)
这现在会在事务完成后调用 __raise_alert,因此不会导致回滚。