Событие init
Событие init из секции event срабатывает
в момент инициализации экземпляра ORM-класса, то есть
при вызове конструктора модели. Обработчик получает
экземпляр первым аргументом, а также позиционные
и именованные аргументы, переданные в конструктор.
Событие позволяет перехватить создание объекта
и заполнить его поля до возврата экземпляра
пользователю.
Синтаксис
from sqlalchemy import event
@event.listens_for(SomeClass, 'init')
def receive_init(target, args, kwargs):
pass
Пример
Давайте создадим модель Article и подпишемся
на событие init, чтобы автоматически
заполнять поле status при создании объекта:
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(100))
text: Mapped[str] = mapped_column(String(255))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@event.listens_for(Article, 'init')
def receive_init(target, args, kwargs):
target.status = 'draft'
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', text='some text', num=1)
session.add(article)
session.commit()
print(article.status)
Результат выполнения кода:
"draft"
Пример
Давайте через событие init прочитаем аргументы,
переданные в конструктор, и выведем их на экран:
from sqlalchemy import create_engine, event, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
text: Mapped[str] = mapped_column(String(255))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@event.listens_for(Article, 'init')
def receive_init(target, args, kwargs):
print('args:', args)
print('kwargs:', kwargs)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
article = Article('article', text='some text', num=1)
Результат выполнения кода:
"args: ('article',)"
"kwargs: {'text': 'some text', 'num': 1}"
Пример
Давайте отменим инициализацию объекта, вернув из
обработчика значение False. В этом случае
конструктор не создаст экземпляр:
from sqlalchemy import create_engine, event, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(100))
text: Mapped[str] = mapped_column(String(255))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@event.listens_for(Article, 'init')
def receive_init(target, args, kwargs):
if kwargs.get('status') == 'banned':
return False
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
article = Article(title='article', status='banned', num=1)
print(article)
Результат выполнения кода:
"None"
Смотрите также
-
функцию
listens_for,
которая подписывает обработчик на событие -
функцию
listen,
которая регистрирует обработчик события -
функцию
remove,
которая удаляет обработчик события -
событие
init_failure,
которое срабатывает при ошибке инициализации