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()
@dirn
rollback
不删除以前保存的模型。我已使用当前设置更新了op。问题是您在会话中调用了
commit
<代码>事务和
会话
是两个不同的会话。你想嵌套它们吗?@dirn如果我只是
添加
模型(不提交),它仍然会存在。我可以添加一个模型并立即回滚。但是查询模型会得到它。我不是想筑巢。我的真实代码与上面一样简单。你需要关闭自动提交。如何使用取决于
db.session
来自何处。这就是炼金术吗?我将其与嵌套的
try except
块和
session.begin(subtransactions=True)
组合使用。谢谢你的帮助!
db = SQLAlchemy(app, session_options={'autocommit': False})