У меня обычно есть такой шаблон при работе с sqlalchemy:
session = get_the_session_one_way_or_another()
try:
# do something with the session
except: # * see comment below
session.rollback()
raise
else:
session.commit()
Чтобы упростить использование, полезно иметь это в качестве менеджера контекста:
@contextmanager
def get_session():
session = get_the_session_one_way_or_another()
try:
yield session
except:
session.rollback()
raise
else:
session.commit()
А потом:
with get_session() as session:
# do something with the session
Если в блоке выдается исключение, менеджер контекста откатит транзакцию.
* Есть пустой except:
, который ловит буквально все. Обычно это не то, что вам нужно, но здесь исключение всегда повторяется, так что это нормально.