Flask 事务失败后回滚
我有一个操作,其中需要使用一些子模型创建父模型。如果创建这些实例中的任何一个失败,整个过程都需要取消。如果出现错误,则数据库中不应存在父模型及其子模型 我的守则如下:Flask 事务失败后回滚,flask,transactions,sqlalchemy,Flask,Transactions,Sqlalchemy,我有一个操作,其中需要使用一些子模型创建父模型。如果创建这些实例中的任何一个失败,整个过程都需要取消。如果出现错误,则数据库中不应存在父模型及其子模型 我的守则如下: transaction = db.engine.connect().begin() try: parent = ParentModel() db.session.add(parent) db.session.commit() child = ChildModel(parent_id=parent
transaction = db.engine.connect().begin()
try:
parent = ParentModel()
db.session.add(parent)
db.session.commit()
child = ChildModel(parent_id=parent.id)
db.session.add(child)
db.session.commit()
# An error occurs. We need to rollback the saved parent model.
raise HTTPException() # from werkzeug
except:
transaction.rollback()
transaction.commit()
我的测试:
def test(self):
# call the above operation
ParentModel.query.filter_by(id=1).first() # returns the parent model
默认情况下,Flask SQLAlchemy启用自动提交。要回滚事务,需要将其关闭。而不是
db = SQLAlchemy(app) # or whatever variation you use
使用
这将允许您在提交或回滚之前将多个对象添加到db.session
通过此更改,您可以删除对
transaction
的引用。要回滚事务,您可以使用transaction.rollback()
@dirnrollback
不删除以前保存的模型。我已使用当前设置更新了op。问题是您在会话中调用了commit
<代码>事务和会话
是两个不同的会话。你想嵌套它们吗?@dirn如果我只是添加
模型(不提交),它仍然会存在。我可以添加一个模型并立即回滚。但是查询模型会得到它。我不是想筑巢。我的真实代码与上面一样简单。你需要关闭自动提交。如何使用取决于db.session
来自何处。这就是炼金术吗?我将其与嵌套的try except
块和session.begin(subtransactions=True)
组合使用。谢谢你的帮助!
db = SQLAlchemy(app, session_options={'autocommit': False})