I'm trying to implement soft deletion in my app. I'd like to keep things atomic so that if an error happens during the soft deletion process, I don't get half deleted stuff.
class User(Base):
__tablename__ = 'users_test_transaction'
id = Column(Integer, primary_key=True)
name = Column(Unicode(200))
password = Column(Unicode(200))
def delete_password(self):
self.password = ""
# Not sure if this is right, but my code has a lot of commit in a
# model's method. This prevents me from using begin_nested().
Session.commit()
def delete(self):
self.delete_password()
raise TypeError("Nothing")
Session.commit()
# Fake view
def delete_user(user):
# I would like this function to happen in a transaction, so that if
# any exception is raised in delete, it rolls back everything. Problem is,
# user.delete() might directly or inderectly call commit().
try:
user.delete()
except:
# Because there's a commit in delete_password, this rollback will do
# nothing.
Session.rollback()
So the problem here is that the rollback does nothing, because there's a commit in the delete_password method (in this example there's only method called, in reality I have multiple methods). I think having stuff being committed in a model's method is antipattern (is it?) but I'd like to know if there's a simple way to get the desired behavior. I tried: