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

Событие after_attach

Событие after_attach относится к событиям сессии и срабатывает после того, как объект был присоединен к сессии через метод add или в результате загрузки из базы данных. Обработчик получает первым параметром саму сессию session, а вторым - экземпляр присоединяемого объекта instance. Событие удобно использовать для инициализации полей, логирования или аудита.

Синтаксис

from sqlalchemy import event @event.listens_for(Session, 'after_attach') def receive_after_attach(session, instance): pass

Пример

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

from sqlalchemy import create_engine, event 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] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) @event.listens_for(Session, 'after_attach') def on_after_attach(session, instance): print(f'attached: {type(instance).__name__}') with Session(engine) as session: article = Article(title='article') session.add(article) session.commit()

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

"attached: Article"

Пример

Событие срабатывает не только при добавлении нового объекта, но и при загрузке существующего из базы данных. Давайте проверим это:

from sqlalchemy import create_engine, event, 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] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add(Article(title='article')) session.commit() @event.listens_for(Session, 'after_attach') def on_after_attach(session, instance): print(f'attached: {instance.title}') with Session(engine) as session: res = session.scalars(select(Article)).all() print(res)

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

"attached: article" "[<__main__.Article object at 0x...>]"

Пример

Давайте используем событие after_attach для автоматической установки значения поля status при присоединении объекта:

from sqlalchemy import create_engine, event 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] status: Mapped[str] = mapped_column(default='draft') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) @event.listens_for(Session, 'after_attach') def set_status(session, instance): if isinstance(instance, Article) and instance.status is None: instance.status = 'new' with Session(engine) as session: article = Article(title='article', status=None) session.add(article) session.commit() print(article.status)

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

"new"

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

  • декоратор listens_for,
    который подписывает функцию на событие
  • функцию listen,
    которая регистрирует обработчик события
  • функцию remove,
    которая удаляет обработчик события
  • событие before_flush,
    которое срабатывает перед сбросом изменений в базу
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить