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

Метод no_autoflush

Метод no_autoflush класса Session возвращает контекстный менеджер, который временно отключает режим автосброса (autoflush) на время выполнения блока кода. Пока автосброс отключён, SQLAlchemy не отправляет накопленные изменения из сессии в базу данных перед выполнением запросов. Это полезно, когда нужно выполнить промежуточный запрос, не затрагивая ещё не зафиксированные объекты. Параметров метод не принимает.

Синтаксис

with session.no_autoflush: # queries here

Пример

Давайте создадим сессию и добавим новый объект, а затем выполним запрос внутри блока no_autoflush, чтобы объект не попал в базу до явного сброса:

from sqlalchemy import create_engine, 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] text: Mapped[str] status: Mapped[str] num: Mapped[int] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article( title='article', text='text', status='new', num=1, ) session.add(article) with session.no_autoflush: res = session.scalars(select(Article)).all() print(res) session.commit()

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

[]

Как видно, объект не был отправлен в базу данных во время запроса, поэтому список оказался пустым.

Пример

Сравним поведение с автосбросом по умолчанию, когда объект попадает в базу прямо перед запросом:

from sqlalchemy import create_engine, 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] text: Mapped[str] status: Mapped[str] num: Mapped[int] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article( title='article', text='text', status='new', num=1, ) session.add(article) res = session.scalars(select(Article)).all() print(len(res)) session.commit()

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

1

Здесь автосброс сработал перед запросом, и объект уже находился в базе данных.

Пример

Метод no_autoflush удобен при работе с уникальными значениями. Покажем, как избежать преждевременного сброса до проверки:

from sqlalchemy import create_engine, 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] text: Mapped[str] status: Mapped[str] num: Mapped[int] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add(Article( title='article', text='text', status='new', num=1, )) with session.no_autoflush: exists = session.scalars( select(Article).where(Article.num == 1) ).first() print(exists) session.commit()

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

None

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

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