Ответ
Транзакции в SQLAlchemy обеспечивают атомарность операций с базой данных (принцип ACID). Управлять ими можно несколькими способами, но предпочтительным является использование контекстных менеджеров.
1. Рекомендуемый способ: Контекстный менеджер Session.begin()
Это самый надежный и лаконичный подход. Он автоматически выполняет commit()
при успешном выходе из блока или rollback()
при возникновении исключения.
from sqlalchemy.orm import Session
# session создается ранее
with Session(engine) as session:
try:
with session.begin():
# Все операции внутри этого блока — часть одной транзакции
user = User(name='John Doe')
session.add(user)
# ... другие операции
# Здесь транзакция автоматически закоммитится
except Exception as e:
# Здесь транзакция автоматически откатится
print(f"Transaction failed: {e}")
2. Явное управление через Session
Классический подход, требующий ручного вызова commit()
и rollback()
.
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
try:
user = User(name='Jane Doe')
session.add(user)
session.commit() # Явный коммит
except:
session.rollback() # Явный откат в случае ошибки
raise
finally:
session.close() # Важно закрывать сессию
3. Уровень Core: Контекстный менеджер Engine.begin()
Подходит для выполнения низкоуровневых SQL-запросов без использования ORM-сессий.
with engine.begin() as connection:
connection.execute(text("UPDATE users SET active=true WHERE id=1"))
# Автоматический commit или rollback
Ключевые принципы:
- Атомарность: Всегда используйте транзакции для операций, которые должны быть выполнены как единое целое (например, перевод денег со счета на счет).
- Безопасность: Контекстные менеджеры (
with ...
) — лучший способ избежать незакрытых сессий или незавершенных транзакций. - Вложенные транзакции: Для более сложных сценариев можно использовать
session.begin_nested()
.