Событие persist
Событие persist относится к событиям маппера
в SQLAlchemy. Оно срабатывает, когда новый объект
впервые добавляется в сессию через метод add
или каскадно через связанный объект. Событие
принимает экземпляр сессии и целевой объект.
Обработчик может быть привязан к конкретному классу
модели или ко всем мапперам сразу.
Синтаксис
from sqlalchemy import event
@event.listens_for(SomeClass, 'persist')
def on_persist(session, instance):
pass
Пример
Давайте создадим модель и подпишемся на событие
persist, чтобы отследить момент добавления
нового объекта в сессию:
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]
text: Mapped[str]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
@event.listens_for(Article, 'persist')
def on_persist(session, instance):
print(f'persist: {instance.title}')
with Session(engine) as session:
article = Article(title='article', text='text')
session.add(article)
session.commit()
Результат выполнения кода:
"persist: article"
Пример
Давайте подпишемся на событие persist для всех
мапперов сразу, передав базовый класс Base:
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]
text: Mapped[str]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
@event.listens_for(Base, 'persist', propagate=True)
def on_persist(session, instance):
print(f'persist: {type(instance).__name__}')
with Session(engine) as session:
article = Article(title='article', text='text')
session.add(article)
session.commit()
Результат выполнения кода:
"persist: Article"
Пример
Давайте сохраним несколько объектов в сессии и
посмотрим, сколько раз сработает событие
persist:
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]
text: Mapped[str]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
counter = {'count': 0}
@event.listens_for(Article, 'persist')
def on_persist(session, instance):
counter['count'] += 1
with Session(engine) as session:
session.add_all([
Article(title='article 1', text='text 1'),
Article(title='article 2', text='text 2'),
Article(title='article 3', text='text 3'),
])
session.commit()
print(f'persist called: {counter["count"]}')
Результат выполнения кода:
"persist called: 3"
Смотрите также
-
декоратор
listens_for,
который привязывает обработчик к событию -
функцию
listen,
которая регистрирует слушателя события -
событие
after_attach,
которое срабатывает после добавления объекта в сессию -
событие
load,
которое срабатывает при загрузке объекта из базы