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

Метод begin_nested

Метод begin_nested класса AsyncSession создает вложенную транзакцию, также известную как SAVEPOINT. Вложенная транзакция позволяет выполнить группу операций и при необходимости откатить только их, не затрагивая внешнюю транзакцию. Метод не принимает обязательных параметров и возвращает объект AsyncSessionTransaction, который можно использовать как асинхронный контекстный менеджер.

Вложенная транзакция работает поверх уже открытой транзакции. Если внешняя транзакция еще не начата, SQLAlchemy начнет ее автоматически. При выходе из блока без ошибок вложенная транзакция фиксируется через RELEASE SAVEPOINT, а при возникновении исключения выполняется ROLLBACK TO SAVEPOINT.

Синтаксис

await session.begin_nested()

Пример

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

import asyncio from sqlalchemy import String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) async def main(): engine = create_async_engine('sqlite+aiosqlite:///:memory:') async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async with AsyncSession(engine) as session: async with session.begin_nested(): session.add(Article(title='article 1', status='new')) await session.commit() res = await session.get(Article, 1) print(res.title) await engine.dispose() asyncio.run(main())

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

"article 1"

Пример

Давайте откатим вложенную транзакцию, чтобы сохранить изменения внешней транзакции:

import asyncio from sqlalchemy import String, select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) async def main(): engine = create_async_engine('sqlite+aiosqlite:///:memory:') async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async with AsyncSession(engine) as session: session.add(Article(title='article 1', status='new')) try: async with session.begin_nested(): session.add(Article(title='article 2', status='new')) raise ValueError('rollback nested') except ValueError: pass await session.commit() res = await session.execute(select(Article)) print([a.title for a in res.scalars().all()]) await engine.dispose() asyncio.run(main())

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

['article 1']

Пример

Давайте используем метод begin_nested без контекстного менеджера и явно вызовем commit и rollback:

import asyncio from sqlalchemy import String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) async def main(): engine = create_async_engine('sqlite+aiosqlite:///:memory:') async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async with AsyncSession(engine) as session: nested = await session.begin_nested() session.add(Article(title='article 1', status='new')) await nested.commit() nested = await session.begin_nested() session.add(Article(title='article 2', status='draft')) await nested.rollback() await session.commit() res = await session.get(Article, 1) print(res.title) await engine.dispose() asyncio.run(main())

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

"article 1"

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

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