Reputation: 3060
I have an operation where a parent model needs to be created with some amount of child models. If the creation of any of these instances fails, the whole thing needs to be canceled. The parent model and its children should not exist in the database if an error is raised.
The code I have:
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()
My test:
def test(self):
# call the above operation
ParentModel.query.filter_by(id=1).first() # returns the parent model
Upvotes: 0
Views: 1389
Reputation: 20719
Flask-SQLAlchemy turns on autocommit by default. In order to rollback a transaction, you need to turn it off. Instead of
db = SQLAlchemy(app) # or whatever variation you use
use
db = SQLAlchemy(app, session_options={'autocommit': False})
This will allow you to add several objects to db.session
before either committing or rolling back.
With this change, you can remove your references to transaction
.
Upvotes: 2