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

Событие before_insert

Событие before_insert из секции event срабатывает перед тем, как объект модели будет вставлен в базу данных. Первым параметром обработчик принимает mapper, вторым - connection, третьим - сам вставляемый target. Событие позволяет изменить значения полей объекта до формирования SQL-запроса INSERT.

Синтаксис

from sqlalchemy import event @event.listens_for(Model, 'before_insert') def handler(mapper, connection, target): pass

Пример

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

from sqlalchemy import create_engine, event, 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)) text: Mapped[str] = mapped_column(String(200), default='') @event.listens_for(Article, 'before_insert') def set_default_title(mapper, connection, target): if not target.title: target.title = 'article' engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='', text='some text') session.add(article) session.commit() print(article.id, article.title)

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

"1 article"

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

INSERT INTO articles (title, text) VALUES ('article', 'some text')

Пример

Давайте в обработчике before_insert проставим поле status в значение 'new' и увеличим счётчик num:

from sqlalchemy import create_engine, event, 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)) status: Mapped[str] = mapped_column(String(20), default='') num: Mapped[int] = mapped_column(default=0) @event.listens_for(Article, 'before_insert') def prepare_article(mapper, connection, target): target.status = 'new' target.num = target.num + 1 engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article', num=5) session.add(article) session.commit() print(article.status, article.num)

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

"new 6"

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

INSERT INTO articles (title, status, num) VALUES ('article', 'new', 6)

Пример

Давайте отменим вставку объекта, установив атрибут target.id вручную, и посмотрим, как обработчик получает доступ к соединению:

from sqlalchemy import create_engine, event, 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)) @event.listens_for(Article, 'before_insert') def log_insert(mapper, connection, target): print('before_insert:', target.title) print('dialect:', connection.dialect.name) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article') session.add(article) session.commit()

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

"before_insert: article" "dialect: sqlite"

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

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