РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
120 of 711 menu

Метод begin_nested класса Session

Метод begin_nested класса Session создает вложенную транзакцию, которая работает внутри уже открытой внешней транзакции. Вложенная транзакция реализуется через механизм SAVEPOINT, поддерживаемый большинством СУБД. Метод не принимает обязательных параметров и возвращает объект SessionTransaction, который можно использовать как контекстный менеджер. Если внутри вложенной транзакции произойдет откат, изменения откатятся только до точки сохранения, а внешняя транзакция останется активной.

Синтаксис

Session.begin_nested()

Пример

Давайте создадим сессию и откроем вложенную транзакцию внутри основной, а затем выполним откат вложенной транзакции:

from sqlalchemy import create_engine, String, select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(50)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: with session.begin(): session.add(Article(title='article 1')) with session.begin_nested(): session.add(Article(title='article 2')) session.rollback() session.add(Article(title='article 3')) res = session.scalars(select(Article)).all() print([a.title for a in res])

Результат выполнения кода:

['article 1', 'article 3']

Как видно из результата, запись article 2 была откачена, потому что она находилась внутри вложенной транзакции, а записи article 1 и article 3 сохранились.

Пример

Давайте посмотрим, какой SQL-запрос генерирует вложенная транзакция при откате:

from sqlalchemy import create_engine, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(50)) engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(engine) with Session(engine) as session: with session.begin(): session.add(Article(title='article')) with session.begin_nested(): session.add(Article(title='article 2')) session.rollback()

Итоговый SQL запрос:

SAVEPOINT sa_savepoint_1 ROLLBACK TO SAVEPOINT sa_savepoint_1

Пример

Давайте получим объект вложенной транзакции через метод get_nested_transaction и проверим ее состояние:

<+python+> from sqlalchemy import create_engine, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(50)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: with session.begin(): nested = session.begin_nested() session.add(Article(title='article')) res = session.get_nested_transaction() print(res is nested) print(res.nested) <-python+>

Результат выполнения кода:

True True

Смотрите также

  • класс Session,
    который управляет сессией работы с базой
  • метод begin,
    который открывает внешнюю транзакцию
  • метод rollback,
    который откатывает текущую транзакцию
  • метод get_nested_transaction,
    который возвращает текущую вложенную транзакцию
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить