События ОРМ

ORM включает в себя широкий спектр крючков, доступных для подписки.

Введение в наиболее часто используемые события ORM см. в разделе Отслеживание запросов, изменений объектов и сессий с помощью событий. Система событий в целом обсуждается в События. События, не относящиеся к ОРМ, такие как события, касающиеся соединений и выполнения низкоуровневых операторов, описаны в Основные мероприятия.

События сессии

Самые основные крючки событий доступны на уровне объекта ORM Session. Здесь перехватываются следующие типы событий:

  • Операции персистенции - процесс ORM flush, который отправляет изменения в базу данных, может быть расширен с помощью событий, которые срабатывают на разных этапах процесса flush, чтобы дополнить или изменить данные, отправляемые в базу данных, или позволить другим вещам происходить, когда происходит персистенция. Подробнее о событиях персистентности читайте в События постоянства.

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

  • События выполнения - Часть модели выполнения 2.0 style, все операторы SELECT против сущностей ORM, а также массовые операторы UPDATE и DELETE вне процесса flush, перехватываются из метода Session.execute() с помощью метода SessionEvents.do_orm_execute(). Подробнее об этом событии читайте на Выполнение событий.

Обязательно прочитайте главу Отслеживание запросов, изменений объектов и сессий с помощью событий, чтобы узнать контекст этих событий.

Object Name Description

SessionEvents

Определите события, характерные для жизненного цикла Session.

class sqlalchemy.orm.SessionEvents

Определите события, характерные для жизненного цикла Session.

например:

from sqlalchemy import event
from sqlalchemy.orm import sessionmaker

def my_before_commit(session):
    print("before commit!")

Session = sessionmaker()

event.listen(Session, "before_commit", my_before_commit)

Функция listen() принимает объекты Session, а также результат возврата sessionmaker() и scoped_session().

Кроме того, он принимает класс Session, который будет применять слушателей ко всем экземплярам Session глобально.

Параметры:
  • raw=False – При значении True аргументом «target», передаваемым в функции слушателей событий, которые работают с отдельными объектами, будет объект управления экземпляра InstanceState, а не сам сопоставленный экземпляр. … versionadded:: 1.3.14

  • restore_load_context=False – Применяется к событию SessionEvents.loaded_as_persistent(). Восстанавливает контекст загрузчика объекта по завершении хука события, так что текущие операции ускоренной загрузки продолжают нацеливаться на объект соответствующим образом. Если объект перемещается в новый контекст загрузчика из этого события, если этот флаг не установлен, выдается предупреждение. … versionadded:: 1.3.14

Классная подпись

класс sqlalchemy.orm.SessionEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.SessionEvents.after_attach(session: Session, instance: _O) None

Выполняется после присоединения экземпляра к сеансу.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_attach')
def receive_after_attach(session, instance):
    "listen for the 'after_attach' event"

    # ... (event handling logic) ...

Это вызывается после добавления, удаления или слияния.

Примечание

Начиная с версии 0.8, это событие срабатывает после того, как объект был полностью связан с сессией, что отличается от предыдущих версий. Для обработчиков событий, которые требуют, чтобы объект еще не был частью состояния сессии (например, обработчики, которые могут автозаполняться, пока целевой объект еще не завершен), рассмотрите новое событие before_attach().

method sqlalchemy.orm.SessionEvents.after_begin(session: Session, transaction: SessionTransaction, connection: Connection) None

Выполняется после начала транзакции на соединении

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_begin')
def receive_after_begin(session, transaction, connection):
    "listen for the 'after_begin' event"

    # ... (event handling logic) ...
Параметры:
  • session – Цель Session.

  • transactionSessionTransaction.

  • connection – Объект Connection, который будет использоваться для SQL-запросов.

method sqlalchemy.orm.SessionEvents.after_bulk_delete(delete_context: _O) None

Событие после вызова унаследованного метода Query.delete().

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_bulk_delete')
def receive_after_bulk_delete(delete_context):
    "listen for the 'after_bulk_delete' event"

    # ... (event handling logic) ...

# DEPRECATED calling style (pre-0.9, will be removed in a future release)
@event.listens_for(SomeSessionClassOrObject, 'after_bulk_delete')
def receive_after_bulk_delete(session, query, query_context, result):
    "listen for the 'after_bulk_delete' event"

    # ... (event handling logic) ...

Изменено в версии 0.9: Событие SessionEvents.after_bulk_delete() теперь принимает аргументы SessionEvents.after_bulk_delete.delete_context. Поддержка функций слушателя, которые принимают предыдущие сигнатуры аргументов, перечисленные выше как «устаревшие», будет удалена в одном из будущих выпусков.

Legacy Feature

Метод SessionEvents.after_bulk_delete() является унаследованным крючком события по состоянию на SQLAlchemy 2.0. Событие не участвует в вызовах 2.0 style с использованием delete(), документированных в ORM UPDATE и DELETE с пользовательскими критериями WHERE. Для использования в стиле 2.0 хук SessionEvents.do_orm_execute() будет перехватывать эти вызовы.

Параметры:

delete_context – объект «контекст удаления», который содержит подробную информацию об обновлении, включая следующие атрибуты: * session - задействованный Session * query - объект Query, на котором была вызвана эта операция обновления. * result - объект CursorResult, возвращенный в результате операции массового DELETE.

Изменено в версии 1.4: update_context больше не имеет связанного с ним объекта QueryContext.

method sqlalchemy.orm.SessionEvents.after_bulk_update(update_context: _O) None

Событие после вызова унаследованного метода Query.update().

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_bulk_update')
def receive_after_bulk_update(update_context):
    "listen for the 'after_bulk_update' event"

    # ... (event handling logic) ...

# DEPRECATED calling style (pre-0.9, will be removed in a future release)
@event.listens_for(SomeSessionClassOrObject, 'after_bulk_update')
def receive_after_bulk_update(session, query, query_context, result):
    "listen for the 'after_bulk_update' event"

    # ... (event handling logic) ...

Изменено в версии 0.9: Событие SessionEvents.after_bulk_update() теперь принимает аргументы SessionEvents.after_bulk_update.update_context. Поддержка функций слушателя, которые принимают предыдущие сигнатуры аргументов, перечисленные выше как «устаревшие», будет удалена в одном из будущих выпусков.

Legacy Feature

Метод SessionEvents.after_bulk_update() является унаследованным крючком события по состоянию на SQLAlchemy 2.0. Событие не участвует в вызовах 2.0 style с использованием update(), документированных в ORM UPDATE и DELETE с пользовательскими критериями WHERE. Для использования в стиле 2.0 хук SessionEvents.do_orm_execute() будет перехватывать эти вызовы.

Параметры:

update_context – объект «контекст обновления», который содержит подробную информацию об обновлении, включая следующие атрибуты: * session - задействованный Session * query - объект Query, для которого была вызвана эта операция обновления. * values - словарь «values», который был передан в Query.update(). * result - словарь CursorResult, возвращенный в результате операции массового UPDATE.

Изменено в версии 1.4: update_context больше не имеет связанного с ним объекта QueryContext.

method sqlalchemy.orm.SessionEvents.after_commit(session: Session) None

Выполняется после того, как произошла фиксация.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_commit')
def receive_after_commit(session):
    "listen for the 'after_commit' event"

    # ... (event handling logic) ...

Примечание

Хук SessionEvents.after_commit() является не per-flush, то есть Session может многократно отправлять SQL в базу данных в рамках транзакции. Для перехвата этих событий используйте события SessionEvents.before_flush(), SessionEvents.after_flush() или SessionEvents.after_flush_postexec().

Примечание

Session не находится в активной транзакции, когда вызывается событие SessionEvents.after_commit(), и поэтому не может испускать SQL. Чтобы выдать SQL, соответствующий каждой транзакции, используйте событие SessionEvents.before_commit().

Параметры:

session – Цель Session.

method sqlalchemy.orm.SessionEvents.after_flush(session: Session, flush_context: UOWTransaction) None

Выполняется после завершения flush, но до вызова commit.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_flush')
def receive_after_flush(session, flush_context):
    "listen for the 'after_flush' event"

    # ... (event handling logic) ...

Обратите внимание, что состояние сессии все еще находится на стадии предварительной очистки, т.е. списки „new“, „dirty“ и „deleted“ все еще показывают состояние до очистки, а также настройки истории для атрибутов экземпляра.

Предупреждение

Это событие запускается после того, как Session выполнил SQL для модификации базы данных, но до того, как изменил свое внутреннее состояние, чтобы отразить эти изменения, включая то, что новые вставленные объекты помещаются в карту идентификации. Операции ORM, выполняемые в рамках этого события, такие как загрузка связанных элементов, могут создавать новые записи в карте идентификации, которые будут немедленно заменены, что иногда приводит к запутанным результатам. Начиная с версии 1.3.9 SQLAlchemy будет выдавать предупреждение об этом событии.

Параметры:
  • session – Цель Session.

  • flush_context – Внутренний объект UOWTransaction, который обрабатывает детали промывки.

method sqlalchemy.orm.SessionEvents.after_flush_postexec(session: Session, flush_context: UOWTransaction) None

Выполняется после завершения промывки и после наступления состояния post-exec.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_flush_postexec')
def receive_after_flush_postexec(session, flush_context):
    "listen for the 'after_flush_postexec' event"

    # ... (event handling logic) ...

Это произойдет, когда списки „new“, „dirty“ и „deleted“ будут в окончательном состоянии. Фактический commit() может произойти или не произойти, в зависимости от того, начал ли flush свою собственную транзакцию или участвовал в более крупной транзакции.

Параметры:
  • session – Цель Session.

  • flush_context – Внутренний объект UOWTransaction, который обрабатывает детали промывки.

method sqlalchemy.orm.SessionEvents.after_rollback(session: Session) None

Выполняется после того, как произошел реальный откат DBAPI.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_rollback')
def receive_after_rollback(session):
    "listen for the 'after_rollback' event"

    # ... (event handling logic) ...

Обратите внимание, что это событие срабатывает только при фактическом откате к базе данных - оно не срабатывает каждый раз при вызове метода Session.rollback(), если транзакция, лежащая в основе DBAPI, уже была откачена. Во многих случаях Session не будет находиться в «активном» состоянии во время этого события, поскольку текущая транзакция недействительна. Чтобы получить Session, который активен после того, как произошел внешний откат, используйте событие SessionEvents.after_soft_rollback(), проверяя флаг Session.is_active.

Параметры:

session – Цель Session.

method sqlalchemy.orm.SessionEvents.after_soft_rollback(session: Session, previous_transaction: SessionTransaction) None

Выполняется после любого произошедшего отката, включая «мягкие» откаты, которые фактически не эмитируются на уровне DBAPI.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_soft_rollback')
def receive_after_soft_rollback(session, previous_transaction):
    "listen for the 'after_soft_rollback' event"

    # ... (event handling logic) ...

Это касается как вложенных, так и внешних откатов, т.е. самого внутреннего отката, который вызывает метод DBAPI rollback(), а также окружающих его вызовов отката, которые только вытаскивают себя из стека транзакций.

Данный Session можно использовать для вызова SQL и Session.query() операций после внешнего отката, предварительно проверив флаг Session.is_active:

@event.listens_for(Session, "after_soft_rollback")
def do_something(session, previous_transaction):
    if session.is_active:
        session.execute("select * from some_table")
Параметры:
  • session – Цель Session.

  • previous_transaction – Объект транзакционного маркера SessionTransaction, который был только что закрыт. Текущий SessionTransaction для данного Session доступен через атрибут Session.transaction.

method sqlalchemy.orm.SessionEvents.after_transaction_create(session: Session, transaction: SessionTransaction) None

Выполняется при создании нового SessionTransaction.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_transaction_create')
def receive_after_transaction_create(session, transaction):
    "listen for the 'after_transaction_create' event"

    # ... (event handling logic) ...

Это событие отличается от SessionEvents.after_begin() тем, что оно возникает для каждой транзакции SessionTransaction в целом, а не при начале транзакций на отдельных соединениях базы данных. Оно также вызывается для вложенных транзакций и субтранзакций и всегда сопровождается соответствующим событием SessionEvents.after_transaction_end() (при условии нормальной работы Session).

Параметры:
  • session – цель Session.

  • transaction – цель SessionTransaction. Чтобы определить, что это внешняя SessionTransaction, а не «субтранзакция» или SAVEPOINT, проверьте, что атрибут SessionTransaction.parent имеет значение None:: @event.listens_for(session, «after_transaction_create») def after_transaction_create(session, transaction): if transaction.parent is None: # работаем с транзакцией верхнего уровня Чтобы определить, что SessionTransaction является SAVEPOINT, используйте атрибут SessionTransaction.nested:: @event.listens_for(session, «after_transaction_create») def after_transaction_create(session, transaction): if transaction.nested: # работать с SAVEPOINT транзакцией

method sqlalchemy.orm.SessionEvents.after_transaction_end(session: Session, transaction: SessionTransaction) None

Выполняется, когда заканчивается интервал SessionTransaction.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'after_transaction_end')
def receive_after_transaction_end(session, transaction):
    "listen for the 'after_transaction_end' event"

    # ... (event handling logic) ...

Это событие отличается от SessionEvents.after_commit() тем, что оно соответствует всем используемым объектам SessionTransaction, включая объекты для вложенных транзакций и субтранзакций, и всегда сопровождается соответствующим событием SessionEvents.after_transaction_create().

Параметры:
  • session – цель Session.

  • transaction – цель SessionTransaction. Чтобы определить, что это самая внешняя SessionTransaction, а не «субтранзакция» или SAVEPOINT, проверьте, что атрибут SessionTransaction.parent имеет значение None:: @event.listens_for(session, «after_transaction_create») def after_transaction_end(session, transaction): if transaction.parent is None: # работаем с транзакцией верхнего уровня Чтобы определить, является ли SessionTransaction SAVEPOINT, используйте атрибут SessionTransaction.nested:: @event.listens_for(session, «after_transaction_create») def after_transaction_end(session, transaction): if transaction.nested: # работать с SAVEPOINT транзакцией

method sqlalchemy.orm.SessionEvents.before_attach(session: Session, instance: _O) None

Выполняется перед присоединением экземпляра к сессии.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_attach')
def receive_before_attach(session, instance):
    "listen for the 'before_attach' event"

    # ... (event handling logic) ...

Вызывается перед тем, как в результате добавления, удаления или слияния объект становится частью сессии.

method sqlalchemy.orm.SessionEvents.before_commit(session: Session) None

Выполняется до вызова commit.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_commit')
def receive_before_commit(session):
    "listen for the 'before_commit' event"

    # ... (event handling logic) ...

Примечание

Хук SessionEvents.before_commit() является не per-flush, то есть Session может многократно отправлять SQL в базу данных в рамках транзакции. Для перехвата этих событий используйте события SessionEvents.before_flush(), SessionEvents.after_flush() или SessionEvents.after_flush_postexec().

Параметры:

session – Цель Session.

method sqlalchemy.orm.SessionEvents.before_flush(session: Session, flush_context: UOWTransaction, instances: Optional[Sequence[_O]]) None

Выполняется до начала процесса смыва.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'before_flush')
def receive_before_flush(session, flush_context, instances):
    "listen for the 'before_flush' event"

    # ... (event handling logic) ...
Параметры:
  • session – Цель Session.

  • flush_context – Внутренний объект UOWTransaction, который обрабатывает детали промывки.

  • instances – Обычно None - это коллекция объектов, которые могут быть переданы методу Session.flush() (обратите внимание, что это использование устарело).

method sqlalchemy.orm.SessionEvents.deleted_to_detached(session: Session, instance: _O) None

Перехват перехода «удален - отсоединен» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'deleted_to_detached')
def receive_deleted_to_detached(session, instance):
    "listen for the 'deleted_to_detached' event"

    # ... (event handling logic) ...

Это событие вызывается, когда удаленный объект выселяется из сессии. Типичный случай, когда это происходит, это когда транзакция для Session, в которой объект был удален, фиксируется; объект переходит из состояния deleted в состояние detached.

Он также вызывается для объектов, которые были удалены в результате флеша при вызове событий Session.expunge_all() или Session.close(), а также если объект индивидуально выводится из удаленного состояния с помощью Session.expunge().

method sqlalchemy.orm.SessionEvents.deleted_to_persistent(session: Session, instance: _O) None

Перехват перехода «deleted to persistent» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'deleted_to_persistent')
def receive_deleted_to_persistent(session, instance):
    "listen for the 'deleted_to_persistent' event"

    # ... (event handling logic) ...

Этот переход происходит только тогда, когда объект, который был успешно удален при флеше, восстанавливается благодаря вызову Session.rollback(). Событие не вызывается ни при каких других обстоятельствах.

method sqlalchemy.orm.SessionEvents.detached_to_persistent(session: Session, instance: _O) None

Перехват перехода «detached to persistent» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'detached_to_persistent')
def receive_detached_to_persistent(session, instance):
    "listen for the 'detached_to_persistent' event"

    # ... (event handling logic) ...

Это событие является специализацией события SessionEvents.after_attach(), которое вызывается только для этого конкретного перехода. Оно вызывается обычно во время вызова Session.add(), а также во время вызова Session.delete(), если объект не был ранее связан с Session (обратите внимание, что объект, помеченный как «удаленный», остается в состоянии «persistent» до тех пор, пока не будет выполнен flush).

Примечание

Если объект становится постоянным в результате вызова Session.delete(), то при вызове этого события объект еще не помечен как удаленный. Чтобы обнаружить удаленные объекты, проверьте флаг deleted, отправленный в событие SessionEvents.persistent_to_detached() to после выполнения flush, или проверьте коллекцию Session.deleted в событии SessionEvents.before_flush(), если удаленные объекты должны быть перехвачены до выполнения flush.

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

attribute sqlalchemy.orm.SessionEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.SessionEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

method sqlalchemy.orm.SessionEvents.do_orm_execute(orm_execute_state: ORMExecuteState) None

Перехватывать выполнение операторов, которые происходят от имени объекта ORM Session.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'do_orm_execute')
def receive_do_orm_execute(orm_execute_state):
    "listen for the 'do_orm_execute' event"

    # ... (event handling logic) ...

Это событие вызывается для всех SQL-запросов верхнего уровня, вызываемых из метода Session.execute(), а также связанных с ним методов, таких как Session.scalars() и Session.scalar(). Начиная с версии SQLAlchemy 1.4, все ORM-запросы, выполняемые через метод Session.execute(), а также связанные с ним методы Session.scalars(), Session.scalar() и т.д. будут участвовать в этом событии. Этот крючок события не применяется к запросам, которые выполняются внутри процесса ORM flush, т.е. к процессу, описанному в Промывка.

Примечание

Крючок события SessionEvents.do_orm_execute() срабатывает только для выполнения операторов ORM, то есть тех, которые вызываются с помощью Session.execute() и подобных методов на объекте Session. Он не срабатывает для операторов, вызываемых только SQLAlchemy Core, т.е. операторов, вызываемых напрямую с помощью Connection.execute() или иным образом исходящих из объекта Engine без участия каких-либо Session. Для перехвата всех SQL-исполнений, независимо от того, используются ли API Core или ORM, смотрите крючки событий ConnectionEvents, такие как ConnectionEvents.before_execute() и ConnectionEvents.before_cursor_execute().

Кроме того, этот крючок событий не применяется к запросам, которые создаются внутри процесса ORM flush, т.е. процесса, описанного в Промывка; чтобы перехватить шаги внутри процесса flush, смотрите крючки событий, описанные в События постоянства, а также События смыва на уровне картографа.

Это событие является событием do_, то есть оно способно заменить операцию, которую обычно выполняет метод Session.execute(). Предполагаемое использование этого события включает схемы шардинга и кэширования результатов, которые могут стремиться вызвать один и тот же оператор через несколько соединений с базой данных, возвращая результат, объединенный из каждого из них, или вообще не вызывать оператор, возвращая данные из кэша.

Хук призван заменить использование метода Query._execute_and_instances, который можно было подклассифицировать до версии SQLAlchemy 1.4.

Параметры:

orm_execute_state – экземпляр ORMExecuteState, который содержит всю информацию о текущем выполнении, а также вспомогательные функции, используемые для получения другой часто необходимой информации. Подробности см. в этом объекте.

См.также

Выполнение событий - документация верхнего уровня о том, как использовать SessionEvents.do_orm_execute()

ORMExecuteState - объект, передаваемый событию SessionEvents.do_orm_execute(), который содержит всю информацию о вызываемом утверждении. Он также предоставляет интерфейс для расширения текущего оператора, опций и параметров, а также опцию, позволяющую программно вызывать оператор в любой момент.

События запросов ORM - включает примеры использования SessionEvents.do_orm_execute()

Кэширование Dogpile - пример интеграции кэширования Dogpile с ORM Session с использованием крючка событий SessionEvents.do_orm_execute().

Горизонтальное разделение - пример/расширение Horizontal Sharding полагается на крючок события SessionEvents.do_orm_execute() для вызова SQL-запроса на нескольких бэкендах и возврата объединенного результата.

Добавлено в версии 1.4.

method sqlalchemy.orm.SessionEvents.loaded_as_persistent(session: Session, instance: _O) None

Перехват перехода «загружен как постоянный» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'loaded_as_persistent')
def receive_loaded_as_persistent(session, instance):
    "listen for the 'loaded_as_persistent' event"

    # ... (event handling logic) ...

Это событие вызывается в процессе загрузки ORM, и вызывается очень похоже на событие InstanceEvents.load(). Однако здесь событие связано с классом или экземпляром Session, а не с маппером или иерархией классов, и легко интегрируется с другими событиями жизненного цикла сессии. Объект гарантированно присутствует в карте идентификации сессии, когда вызывается это событие.

Примечание

Это событие вызывается в процессе загрузчика до того, как может быть завершена работа жаждущих загрузчиков, и состояние объекта может быть неполным. Кроме того, вызов операций обновления на уровне строк для объекта поместит объект в новый контекст загрузчика, вмешиваясь в существующий контекст загрузки. См. примечание к InstanceEvents.load() для получения информации об использовании параметра SessionEvents.restore_load_context, который работает так же, как и InstanceEvents.restore_load_context, для решения этого сценария.

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

method sqlalchemy.orm.SessionEvents.pending_to_persistent(session: Session, instance: _O) None

Перехват перехода «pending to persistent» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'pending_to_persistent')
def receive_pending_to_persistent(session, instance):
    "listen for the 'pending_to_persistent' event"

    # ... (event handling logic) ...

Это событие вызывается в рамках процесса flush и аналогично сканированию коллекции Session.new в рамках события SessionEvents.after_flush(). Однако в данном случае объект уже был переведен в постоянное состояние на момент вызова события.

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

method sqlalchemy.orm.SessionEvents.pending_to_transient(session: Session, instance: _O) None

Перехват перехода «ожидание - переход» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'pending_to_transient')
def receive_pending_to_transient(session, instance):
    "listen for the 'pending_to_transient' event"

    # ... (event handling logic) ...

Этот менее распространенный переход происходит, когда ожидающий объект, который не был удален, вытесняется из сессии; это может произойти, когда метод Session.rollback() откатывает транзакцию, или когда используется метод Session.expunge().

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

method sqlalchemy.orm.SessionEvents.persistent_to_deleted(session: Session, instance: _O) None

Перехват перехода «persistent to deleted» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_deleted')
def receive_persistent_to_deleted(session, instance):
    "listen for the 'persistent_to_deleted' event"

    # ... (event handling logic) ...

Это событие вызывается, когда идентификатор постоянного объекта удаляется из базы данных в рамках флеша, однако объект остается связанным с Session до завершения транзакции.

Если транзакция откатывается, объект снова переходит в постоянное состояние, и вызывается событие SessionEvents.deleted_to_persistent(). Если транзакция зафиксирована, объект становится отсоединенным, что вызовет событие SessionEvents.deleted_to_detached().

Обратите внимание, что хотя метод Session.delete() является основным публичным интерфейсом для пометки объекта как удаленного, многие объекты удаляются по каскадным правилам, которые не всегда определяются до момента flush. Поэтому не существует способа поймать каждый объект, который будет удален до тех пор, пока не начнется flush. Поэтому событие SessionEvents.persistent_to_deleted() вызывается в конце flush.

method sqlalchemy.orm.SessionEvents.persistent_to_detached(session: Session, instance: _O) None

Перехват перехода «persistent to detached» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_detached')
def receive_persistent_to_detached(session, instance):
    "listen for the 'persistent_to_detached' event"

    # ... (event handling logic) ...

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

  • используя такой метод, как Session.expunge() или Session.close()

  • Вызов метода Session.rollback(), когда объект был частью оператора INSERT для транзакции этой сессии

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

  • deleted – булево. Если True, указывает, что этот объект перешел в состояние detached, поскольку был помечен как удаленный и смыт.

method sqlalchemy.orm.SessionEvents.persistent_to_transient(session: Session, instance: _O) None

Перехват перехода «от постоянного к переходному» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'persistent_to_transient')
def receive_persistent_to_transient(session, instance):
    "listen for the 'persistent_to_transient' event"

    # ... (event handling logic) ...

Этот менее распространенный переход происходит, когда отложенный объект, который был удален, вытесняется из сессии; это может произойти, когда метод Session.rollback() откатывает транзакцию.

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

method sqlalchemy.orm.SessionEvents.transient_to_pending(session: Session, instance: _O) None

Перехват перехода «переходный в ожидающий» для определенного объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeSessionClassOrObject, 'transient_to_pending')
def receive_transient_to_pending(session, instance):
    "listen for the 'transient_to_pending' event"

    # ... (event handling logic) ...

Это событие является специализацией события SessionEvents.after_attach(), которое вызывается только для данного конкретного перехода. Обычно оно вызывается во время вызова Session.add().

Параметры:
  • session – цель Session

  • instance – экземпляр ORM-сопоставления, с которым выполняется операция.

События картографа

Крючки событий маппера охватывают события, происходящие с отдельными или несколькими объектами Mapper, которые являются центральным конфигурационным объектом, отображающим определенный пользователем класс на объект Table. Типы событий, которые происходят на уровне Mapper, включают:

  • Операции персистентности для каждого объекта - наиболее популярными крючками маппера являются крючки для единицы работы, такие как MapperEvents.before_insert(), MapperEvents.after_update() и т.д. Эти события отличаются от более крупнозернистых событий уровня сессии, таких как SessionEvents.before_flush(), тем, что они происходят внутри процесса flush на основе каждого объекта; в то время как более мелкозернистая деятельность над объектом более проста, доступность функций Session ограничена.

  • События конфигурации маппера - другой основной класс крючков маппера - это те, которые происходят при отображении класса, при завершении работы маппера и при настройке наборов мапперов для обращения друг к другу. Эти события включают MapperEvents.instrument_class(), MapperEvents.before_mapper_configured() и MapperEvents.mapper_configured() на уровне отдельных Mapper и MapperEvents.before_configured() и MapperEvents.after_configured() на уровне коллекций Mapper объектов.

Object Name Description

MapperEvents

Определите события, характерные для сопоставлений.

class sqlalchemy.orm.MapperEvents

Определите события, характерные для сопоставлений.

например:

from sqlalchemy import event

def my_before_insert_listener(mapper, connection, target):
    # execute a stored procedure upon INSERT,
    # apply the value to the row to be inserted
    target.calculated_value = connection.execute(
        text("select my_special_function(%d)" % target.special_number)
    ).scalar()

# associate the listener function with SomeClass,
# to execute during the "before_insert" hook
event.listen(
    SomeClass, 'before_insert', my_before_insert_listener)

Доступные цели включают:

  • сопоставленные классы

  • несопоставленные суперклассы сопоставленных или подлежащих сопоставлению классов (с использованием флага propagate=True)

  • Mapper объекты

  • сам класс Mapper указывает на прослушивание всех картографов.

События маппера обеспечивают доступ к критическим секциям маппера, включая те, которые связаны с инструментарием объектов, загрузкой объектов и сохранением объектов. В частности, методы персистенции MapperEvents.before_insert() и MapperEvents.before_update() являются популярными местами для дополнения сохраняемого состояния - однако, эти методы работают с несколькими существенными ограничениями. Пользователю предлагается оценить методы SessionEvents.before_flush() и SessionEvents.after_flush() как более гибкие и удобные крючки для применения дополнительного состояния базы данных во время флеша.

При использовании MapperEvents для функции listen() доступны несколько модификаторов.

Параметры:
  • propagate=False – Когда True, слушатель событий должен быть применен ко всем наследующим мапперам и/или мапперам наследующих классов, а также к любому мапперу, который является целью этого слушателя.

  • raw=False – При значении True аргументом «target», передаваемым соответствующим функциям слушателя событий, будет объект управления экземпляра InstanceState, а не сам сопоставленный экземпляр.

  • retval=False – когда True, функция события, определенная пользователем, должна иметь возвращаемое значение, целью которого является либо управление последующим распространением события, либо иное изменение операции, выполняемой картографом. Возможными значениями возврата являются: * sqlalchemy.orm.interfaces.EXT_CONTINUE - продолжить обработку события в нормальном режиме. * sqlalchemy.orm.interfaces.EXT_STOP - отмена всех последующих обработчиков событий в цепочке. * другие значения - возвращаемое значение, заданное конкретными слушателями.

Классная подпись

класс sqlalchemy.orm.MapperEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.MapperEvents.after_configured() None

Вызывается после того, как серия картографов была настроена.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_configured')
def receive_after_configured():
    "listen for the 'after_configured' event"

    # ... (event handling logic) ...

Событие MapperEvents.after_configured() вызывается каждый раз, когда вызывается функция configure_mappers(), после того, как она выполнила свою работу. configure_mappers() обычно вызывается автоматически при первом использовании отображений, а также каждый раз, когда новые отображения становятся доступными и обнаруживается новое использование отображений.

Противопоставьте это событие событию MapperEvents.mapper_configured(), которое вызывается на основе каждого маппера во время выполнения операции конфигурирования; в отличие от этого события, когда вызывается это событие, все кросс-конфигурации (например, обратные ссылки) также будут доступны для всех мапперов, которые были в ожидании. Также в отличие от MapperEvents.before_configured(), которое вызывается до того, как серия картографов была сконфигурирована.

Это событие может только быть применено к классу Mapper, а не к отдельным отображениям или отображенным классам. Оно вызывается только для всех отображений в целом:

from sqlalchemy.orm import Mapper

@event.listens_for(Mapper, "after_configured")
def go():
    # ...

Теоретически это событие вызывается один раз для каждого приложения, но фактически оно вызывается каждый раз, когда новые отображения были затронуты вызовом configure_mappers(). Если новые отображения создаются после того, как существующие уже были использованы, это событие, скорее всего, будет вызвано снова. Чтобы гарантировать, что конкретное событие будет вызвано только один раз и не более, можно применить аргумент once=True (новый в 0.9.4):

from sqlalchemy.orm import mapper

@event.listens_for(mapper, "after_configured", once=True)
def go():
    # ...
method sqlalchemy.orm.MapperEvents.after_delete(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта после того, как был выпущен оператор DELETE, соответствующий этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_delete')
def receive_after_delete(mapper, connection, target):
    "listen for the 'after_delete' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

Это событие используется для выполнения дополнительных SQL-запросов на данном соединении, а также для выполнения специфических для приложения бухгалтерских операций, связанных с событием удаления.

Это событие часто вызывается для партии объектов одного класса после того, как их заявления DELETE были выпущены одновременно на предыдущем шаге.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выполнения операторов DELETE для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – удаляемый сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

method sqlalchemy.orm.MapperEvents.after_insert(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта после выполнения оператора INSERT, соответствующего этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_insert')
def receive_after_insert(mapper, connection, target):
    "listen for the 'after_insert' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

Это событие используется для изменения состояния экземпляра только на языке Python после выполнения INSERT, а также для выполнения дополнительных SQL-запросов на данном соединении.

Это событие часто вызывается для партии объектов одного класса после того, как их операторы INSERT были выпущены одновременно на предыдущем шаге. В крайне редких случаях, когда это нежелательно, объект Mapper может быть настроен на batch=False, что приведет к тому, что партии экземпляров будут разбиты на отдельные (и более низкопроизводительные) шаги event->persist->event.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выполнения операторов INSERT для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – сопоставленный экземпляр, который сохраняется. Если событие настроено с параметром raw=True, то вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

method sqlalchemy.orm.MapperEvents.after_mapper_constructed(mapper: Mapper[_O], class_: Type[_O]) None

Получите класс и маппер, когда Mapper будет полностью построен.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_mapper_constructed')
def receive_after_mapper_constructed(mapper, class_):
    "listen for the 'after_mapper_constructed' event"

    # ... (event handling logic) ...

Это событие вызывается после завершения работы начального конструктора для Mapper. Это происходит после события MapperEvents.instrument_class() и после того, как Mapper выполнил начальный проход по своим аргументам для создания своей коллекции объектов MapperProperty, которые доступны через метод Mapper.get_property() и атрибут Mapper.iterate_properties.

Это событие отличается от события MapperEvents.before_mapper_configured() тем, что оно вызывается в конструкторе для Mapper, а не в процессе registry.configure(). В настоящее время только это событие подходит для обработчиков, которые хотят создать дополнительные сопоставленные классы в ответ на построение этого Mapper, которые будут частью того же шага configure при следующем запуске registry.configure().

Добавлено в версии 2.0.2.

См.также

Версионирование объектов - пример, иллюстрирующий использование события MapperEvents.before_mapper_configured() для создания новых мапперов для записи истории изменений-аудита объектов.

method sqlalchemy.orm.MapperEvents.after_update(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта после того, как был выпущен оператор UPDATE, соответствующий этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'after_update')
def receive_after_update(mapper, connection, target):
    "listen for the 'after_update' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

Это событие используется для изменения состояния экземпляра только на языке Python после выполнения UPDATE, а также для выполнения дополнительных SQL-запросов на данном соединении.

Этот метод вызывается для всех экземпляров, которые помечены как «грязные», даже для тех, которые не имеют чистых изменений в своих атрибутах на основе столбцов, и для которых не выполнялся оператор UPDATE. Объект помечается как «грязный», когда для любого из его атрибутов, основанных на столбцах, вызывается операция «set attribute» или когда изменяется любая из его коллекций. Если во время обновления ни один атрибут на основе столбцов не имеет чистых изменений, оператор UPDATE не будет выпущен. Это означает, что отправка экземпляра в MapperEvents.after_update() не является не гарантией того, что был выпущен оператор UPDATE.

Чтобы определить, изменились ли атрибуты объекта на основе столбцов в чистом виде, что привело к появлению оператора UPDATE, используйте object_session(instance).is_modified(instance, include_collections=False).

Это событие часто вызывается для партии объектов одного класса после того, как их заявления UPDATE были выпущены одновременно на предыдущем шаге. В крайне редких случаях, когда это нежелательно, Mapper можно настроить batch=False, что приведет к тому, что партии экземпляров будут разбиты на отдельные (и более низкопроизводительные) шаги event->persist->event.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выпуска UPDATE-запросов для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – сопоставленный экземпляр, который сохраняется. Если событие настроено с параметром raw=True, то вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

method sqlalchemy.orm.MapperEvents.before_configured() None

Вызывается перед конфигурированием ряда картографов.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_configured')
def receive_before_configured():
    "listen for the 'before_configured' event"

    # ... (event handling logic) ...

Событие MapperEvents.before_configured() вызывается каждый раз, когда вызывается функция configure_mappers(), до того, как эта функция выполнит свою работу. configure_mappers() обычно вызывается автоматически при первом использовании отображений, а также каждый раз, когда новые отображения становятся доступными и обнаруживается новое использование отображений.

Это событие может только быть применено к классу Mapper, а не к отдельным отображениям или отображенным классам. Оно вызывается только для всех отображений в целом:

from sqlalchemy.orm import Mapper

@event.listens_for(Mapper, "before_configured")
def go():
    ...

В отличие от MapperEvents.after_configured(), которое вызывается после настройки серии мапперов, а также MapperEvents.before_mapper_configured() и MapperEvents.mapper_configured(), которые вызываются по каждому мапперу.

Теоретически это событие вызывается один раз для каждого приложения, но на самом деле оно вызывается каждый раз, когда новые отображения должны быть затронуты вызовом configure_mappers(). Если новые отображения создаются после того, как существующие уже были использованы, это событие, скорее всего, будет вызвано снова. Чтобы гарантировать, что конкретное событие будет вызвано только один раз и не более, можно применить аргумент once=True (новый в 0.9.4):

from sqlalchemy.orm import mapper

@event.listens_for(mapper, "before_configured", once=True)
def go():
    ...
method sqlalchemy.orm.MapperEvents.before_delete(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта до того, как будет выпущен оператор DELETE, соответствующий этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_delete')
def receive_before_delete(mapper, connection, target):
    "listen for the 'before_delete' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

Это событие используется для выполнения дополнительных SQL-запросов на данном соединении, а также для выполнения специфических для приложения бухгалтерских операций, связанных с событием удаления.

Это событие часто вызывается для партии объектов одного класса, прежде чем их заявления DELETE будут выпущены одновременно на следующем шаге.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выполнения операторов DELETE для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – удаляемый сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

method sqlalchemy.orm.MapperEvents.before_insert(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта до того, как будет выдан оператор INSERT, соответствующий этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_insert')
def receive_before_insert(mapper, connection, target):
    "listen for the 'before_insert' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

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

Это событие часто вызывается для партии объектов одного класса перед тем, как их INSERT-запросы будут выданы одновременно на более позднем этапе. В крайне редких случаях, когда это нежелательно, объект Mapper может быть настроен на batch=False, что приведет к тому, что партии экземпляров будут разбиты на отдельные (и более низкопроизводительные) шаги event->persist->event.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выполнения операторов INSERT для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – сопоставленный экземпляр, который сохраняется. Если событие настроено с параметром raw=True, то вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

method sqlalchemy.orm.MapperEvents.before_mapper_configured(mapper: Mapper[_O], class_: Type[_O]) None

Вызывается непосредственно перед конфигурированием определенного картографа.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_mapper_configured')
def receive_before_mapper_configured(mapper, class_):
    "listen for the 'before_mapper_configured' event"

    # ... (event handling logic) ...

Это событие предназначено для того, чтобы позволить пропустить определенный маппер на этапе конфигурирования, возвращая символ interfaces.EXT_SKIP, который указывает вызову configure_mappers(), что этот конкретный маппер (или иерархия мапперов, если используется propagate=True) должен быть пропущен в текущем запуске конфигурации. Когда один или несколько картографов пропущены, флаг «new mappers» останется установленным, что означает, что функция configure_mappers() будет по-прежнему вызываться при использовании картографов, чтобы продолжить попытки конфигурирования всех доступных картографов.

По сравнению с другими событиями уровня configure, MapperEvents.before_configured(), MapperEvents.after_configured() и MapperEvents.mapper_configured(), событие :meth;`.MapperEvents.before_mapper_configured` обеспечивает значимое возвращаемое значение, когда оно зарегистрировано с параметром retval=True.

Добавлено в версии 1.3.

например:

from sqlalchemy.orm import EXT_SKIP

Base = declarative_base()

DontConfigureBase = declarative_base()

@event.listens_for(
    DontConfigureBase,
    "before_mapper_configured", retval=True, propagate=True)
def dont_configure(mapper, cls):
    return EXT_SKIP
method sqlalchemy.orm.MapperEvents.before_update(mapper: Mapper[_O], connection: Connection, target: _O) None

Получение экземпляра объекта до того, как будет выпущен оператор UPDATE, соответствующий этому экземпляру.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'before_update')
def receive_before_update(mapper, connection, target):
    "listen for the 'before_update' event"

    # ... (event handling logic) ...

Примечание

это событие только относится к session flush operation и не относится к операциям ORM DML, описанным в Операции INSERT, UPDATE и DELETE с поддержкой ORM. Чтобы перехватить события ORM DML, используйте SessionEvents.do_orm_execute().

Это событие используется для изменения локальных, не связанных с объектом, атрибутов экземпляра до того, как произойдет UPDATE, а также для запуска дополнительных SQL-запросов на данном соединении.

Этот метод вызывается для всех экземпляров, которые помечены как «грязные», даже для тех, которые не имеют чистых изменений в своих атрибутах на основе столбцов. Объект помечается как «грязный», когда для любого из его атрибутов на основе столбцов вызывается операция «set attribute» или когда изменяется любая из его коллекций. Если во время обновления ни один атрибут на основе столбцов не имеет чистых изменений, оператор UPDATE не будет выдан. Это означает, что отправка экземпляра в MapperEvents.before_update() не является не гарантией того, что будет выпущен оператор UPDATE, хотя вы можете повлиять на результат, изменив атрибуты так, чтобы чистое изменение значения действительно существовало.

Чтобы определить, есть ли в атрибутах объекта на основе столбцов чистые изменения, и поэтому будет сгенерирован оператор UPDATE, используйте object_session(instance).is_modified(instance, include_collections=False).

Это событие часто вызывается для партии объектов одного класса, прежде чем их заявления UPDATE будут выпущены одновременно на более позднем шаге. В крайне редких случаях, когда это нежелательно, Mapper можно настроить batch=False, что приведет к тому, что партии экземпляров будут разбиты на отдельные (и более низкопроизводительные) шаги event->persist->event.

Предупреждение

События flush на уровне маппера допускают только очень ограниченные операции, только над атрибутами, локальными для обрабатываемой строки, а также позволяют выдавать любой SQL на данном Connection. Пожалуйста, прочитайте полностью примечания в События смыва на уровне картографа для рекомендаций по использованию этих методов; в целом, метод SessionEvents.before_flush() должен быть предпочтительным для общих изменений на уровне flush.

Параметры:
  • mapperMapper, который является целью этого события.

  • connectionConnection, используемый для выпуска UPDATE-запросов для данного экземпляра. Это позволяет получить доступ к текущей транзакции в целевой базе данных, специфичной для данного экземпляра.

  • target – сопоставленный экземпляр, который сохраняется. Если событие настроено с параметром raw=True, то вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

Результат:

Данное событие не поддерживает никаких возвращаемых значений.

attribute sqlalchemy.orm.MapperEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.MapperEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

method sqlalchemy.orm.MapperEvents.instrument_class(mapper: Mapper[_O], class_: Type[_O]) None

Получение класса при первом построении отображателя, до применения инструментации к отображаемому классу.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'instrument_class')
def receive_instrument_class(mapper, class_):
    "listen for the 'instrument_class' event"

    # ... (event handling logic) ...

Это событие является самой ранней фазой построения картографа. Большинство атрибутов картографа еще не инициализированы. Для получения события на начальном этапе построения картографа, когда доступны основные состояния, такие как коллекция Mapper.attrs, событие MapperEvents.after_mapper_constructed() может быть лучшим выбором.

Этот слушатель может быть применен либо к классу Mapper в целом, либо к любому не отображенному классу, который служит базой для классов, которые будут отображены (с помощью флага propagate=True):

Base = declarative_base()

@event.listens_for(Base, "instrument_class", propagate=True)
def on_new_class(mapper, cls_):
    " ... "
Параметры:
  • mapperMapper, который является целью этого события.

  • class_ – сопоставленный класс.

method sqlalchemy.orm.MapperEvents.mapper_configured(mapper: Mapper[_O], class_: Type[_O]) None

Вызывается, когда определенный картограф завершил свою собственную конфигурацию в пределах области действия вызова configure_mappers().

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'mapper_configured')
def receive_mapper_configured(mapper, class_):
    "listen for the 'mapper_configured' event"

    # ... (event handling logic) ...

Событие MapperEvents.mapper_configured() вызывается для каждого маппера, который встречается, когда функция configure_mappers() проходит по текущему списку еще не сконфигурированных мапперов. configure_mappers() обычно вызывается автоматически при первом использовании отображений, а также каждый раз, когда новые отображения становятся доступными и обнаруживается новое использование отображения.

Когда событие вызывается, отобразитель должен быть в своем окончательном состоянии, но не включая обратные ссылки, которые могут быть вызваны из других отобразителей; они все еще могут быть в ожидании в рамках операции конфигурации. Двунаправленные отношения, которые вместо этого конфигурируются через аргумент relationship.back_populates, *будут полностью доступны, так как этот стиль отношений не зависит от других, возможно, неконфигурированных картографов, чтобы узнать, что они существуют.

Для события, в котором гарантированно будут готовы все отображения, включая обратные ссылки, которые определены только на других отображениях, используйте событие MapperEvents.after_configured(); это событие вызывается только после того, как все известные отображения были полностью настроены.

Событие MapperEvents.mapper_configured(), в отличие от MapperEvents.before_configured() или MapperEvents.after_configured(), вызывается для каждого маппера/класса отдельно, и маппер передается в само событие. Оно также вызывается ровно один раз для конкретного маппера. Поэтому событие полезно для конфигурационных шагов, которые выгодно вызывать только один раз для конкретного маппера, и которые не требуют, чтобы конфигурации «backref» были обязательно готовы.

Параметры:
  • mapperMapper, который является целью этого события.

  • class_ – сопоставленный класс.

События экземпляра

События экземпляра сосредоточены на построении сопоставленных экземпляров ORM, включая моменты, когда они инстанцируются как объекты transient, когда они загружаются из базы данных и становятся объектами persistent, а также когда над объектом происходят операции обновления или истечения срока действия базы данных.

Object Name Description

InstanceEvents

Определите события, характерные для жизненного цикла объекта.

class sqlalchemy.orm.InstanceEvents

Определите события, характерные для жизненного цикла объекта.

например:

from sqlalchemy import event

def my_load_listener(target, context):
    print("on load!")

event.listen(SomeClass, 'load', my_load_listener)

Доступные цели включают:

  • сопоставленные классы

  • несопоставленные суперклассы сопоставленных или подлежащих сопоставлению классов (с использованием флага propagate=True)

  • Mapper объекты

  • сам класс Mapper указывает на прослушивание всех картографов.

События экземпляра тесно связаны с событиями mapper, но они более специфичны для экземпляра и его инструментария, а не для его системы сохранения.

При использовании InstanceEvents для функции listen() доступны несколько модификаторов.

Параметры:
  • propagate=False – При значении True слушатель событий должен быть применен ко всем наследующим классам, а также к классу, который является целью этого слушателя.

  • raw=False – При значении True аргументом «target», передаваемым соответствующим функциям слушателя событий, будет объект управления экземпляра InstanceState, а не сам сопоставленный экземпляр.

  • restore_load_context=False – Применяется к событиям InstanceEvents.load() и InstanceEvents.refresh(). Восстанавливает контекст загрузчика объекта по завершении перехвата события, так что текущие операции ускоренной загрузки продолжают нацеливаться на объект соответствующим образом. Предупреждение выдается, если объект перемещается в новый контекст загрузчика из одного из этих событий, если этот флаг не установлен. … versionadded:: 1.3.14

Классная подпись

класс sqlalchemy.orm.InstanceEvents (sqlalchemy.event.Events)

attribute sqlalchemy.orm.InstanceEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.InstanceEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

method sqlalchemy.orm.InstanceEvents.expire(target: _O, attrs: Optional[Iterable[str]]) None

Получение экземпляра объекта после истечения срока действия его атрибутов или некоторого подмножества.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'expire')
def receive_expire(target, attrs):
    "listen for the 'expire' event"

    # ... (event handling logic) ...

„keys“ - это список имен атрибутов. Если None, то все состояние было просрочено.

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • attrs – последовательность имен атрибутов, срок действия которых истек, или None, если срок действия всех атрибутов истек.

method sqlalchemy.orm.InstanceEvents.first_init(manager: ClassManager[_O], cls: Type[_O]) None

Вызывается при вызове первого экземпляра определенного отображения.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'first_init')
def receive_first_init(manager, cls):
    "listen for the 'first_init' event"

    # ... (event handling logic) ...

Это событие вызывается, когда метод __init__ класса вызывается в первый раз для данного класса. Событие вызывается до того, как произойдет __init__, а также до того, как будет вызвано событие InstanceEvents.init().

method sqlalchemy.orm.InstanceEvents.init(target: _O, args: Any, kwargs: Any) None

Получение экземпляра при вызове его конструктора.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'init')
def receive_init(target, args, kwargs):
    "listen for the 'init' event"

    # ... (event handling logic) ...

Этот метод вызывается только во время пользовательского конструирования объекта, в сочетании с конструктором объекта, например, его методом __init__. Он не вызывается при загрузке объекта из базы данных; для перехвата загрузки базы данных см. событие InstanceEvents.load().

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

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • args – позиционные аргументы, передаваемые методу __init__. Они передаются в виде кортежа и в настоящее время являются неизменяемыми.

  • kwargs – аргументы ключевого слова, передаваемые методу __init__. Эта структура может быть изменена на месте.

method sqlalchemy.orm.InstanceEvents.init_failure(target: _O, args: Any, kwargs: Any) None

Получите экземпляр, когда его конструктор был вызван и вызвал исключение.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'init_failure')
def receive_init_failure(target, args, kwargs):
    "listen for the 'init_failure' event"

    # ... (event handling logic) ...

Этот метод вызывается только во время пользовательского конструирования объекта, в сочетании с конструктором объекта, например, его методом __init__. Он не вызывается при загрузке объекта из базы данных.

Событие вызывается после того, как поймано исключение, поднятое методом __init__. После вызова события исходное исключение повторно поднимается наружу, так что при конструировании объекта все равно возникает исключение. Фактическое исключение и трассировка стека должны присутствовать в sys.exc_info().

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • args – позиционные аргументы, которые были переданы методу __init__.

  • kwargs – аргументы ключевого слова, которые были переданы методу __init__.

method sqlalchemy.orm.InstanceEvents.load(target: _O, context: QueryContext) None

Получение экземпляра объекта после его создания с помощью __new__ и после заселения начальных атрибутов.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'load')
def receive_load(target, context):
    "listen for the 'load' event"

    # ... (event handling logic) ...

Обычно это происходит, когда экземпляр создается на основе входящих строк результатов, и вызывается только один раз за все время существования данного экземпляра.

Предупреждение

Во время загрузки результирующей строки это событие вызывается, когда обрабатывается первая строка, полученная для данного экземпляра. При использовании ускоренной загрузки с атрибутами, ориентированными на коллекции, дополнительные строки, которые должны быть загружены / обработаны для загрузки последующих элементов коллекции, еще не произошли. Это приводит к тому, что коллекции не будут загружены полностью, а также к тому, что если в обработчике этого события произойдет операция, которая вызовет другую операцию загрузки базы данных для объекта, «контекст загрузки» для объекта может измениться и помешать существующим операциям ускоренной загрузки, которые еще выполняются.

Примеры того, что может привести к изменению «контекста загрузки» в обработчике события, включают, но не обязательно ограничиваются этим:

  • обращение к отложенным атрибутам, которые не были частью строки, вызовет операцию «undefer» и обновит объект

  • обращение к атрибутам подкласса объединенного наследования, которые не были частью строки, вызовет операцию обновления.

Начиная с версии SQLAlchemy 1.3.14, при возникновении этого события выдается предупреждение. Опция InstanceEvents.restore_load_context может быть использована в событии для предотвращения этого предупреждения; это обеспечит сохранение существующего контекста загрузки для объекта после вызова события:

@event.listens_for(
    SomeClass, "load", restore_load_context=True)
def on_load(instance, context):
    instance.some_unloaded_attribute

Изменено в версии 1.3.14: Добавлены флаги InstanceEvents.restore_load_context и SessionEvents.restore_load_context, применяемые к событиям «on load», которые гарантируют, что контекст загрузки объекта будет восстановлен после завершения хука события; предупреждение выдается, если контекст загрузки объекта изменяется без установки этого флага.

Событие InstanceEvents.load() также доступно в формате декоратора класса-метода под названием reconstructor().

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • contextQueryContext, соответствующий текущему выполняемому Query. Этот аргумент может быть None, если нагрузка не соответствует Query, например, во время Session.merge().

method sqlalchemy.orm.InstanceEvents.pickle(target: _O, state_dict: _InstanceDict) None

Получение экземпляра объекта, когда связанное с ним состояние находится в стадии pickled.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'pickle')
def receive_pickle(target, state_dict):
    "listen for the 'pickle' event"

    # ... (event handling logic) ...
Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • state_dict – словарь, возвращаемый командой __getstate__, содержащий состояние, которое нужно замариновать.

method sqlalchemy.orm.InstanceEvents.refresh(target: _O, context: QueryContext, attrs: Optional[Iterable[str]]) None

Получение экземпляра объекта после обновления одного или нескольких атрибутов из запроса.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'refresh')
def receive_refresh(target, context, attrs):
    "listen for the 'refresh' event"

    # ... (event handling logic) ...

В отличие от метода InstanceEvents.load(), который вызывается при первой загрузке объекта из запроса.

Примечание

Это событие вызывается в процессе загрузчика до того, как может быть завершена работа жаждущих загрузчиков, и состояние объекта может быть неполным. Кроме того, вызов операций обновления на уровне строк для объекта поместит объект в новый контекст загрузчика, вмешиваясь в существующий контекст загрузки. См. примечание о InstanceEvents.load() для получения информации об использовании параметра InstanceEvents.restore_load_context для решения этого сценария.

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • contextQueryContext, соответствующий текущему Query в процессе выполнения.

  • attrs – последовательность имен атрибутов, которые были заполнены, или None, если были заполнены все сопоставленные со столбцами не отложенные атрибуты.

См.также

InstanceEvents.load()

method sqlalchemy.orm.InstanceEvents.refresh_flush(target: _O, flush_context: UOWTransaction, attrs: Optional[Iterable[str]]) None

Получение экземпляра объекта после обновления одного или нескольких атрибутов, содержащих обработчик по умолчанию или onupdate на уровне колонок, во время сохранения состояния объекта.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'refresh_flush')
def receive_refresh_flush(target, flush_context, attrs):
    "listen for the 'refresh_flush' event"

    # ... (event handling logic) ...

Это событие аналогично событию InstanceEvents.refresh() за исключением того, что оно вызывается в рамках процесса промывки единицы работы и включает только столбцы, не являющиеся первичными ключами, которые имеют обработчики по умолчанию или обновлению на уровне столбцов, включая вызываемые файлы Python, а также обработчики по умолчанию и триггеры на стороне сервера, которые могут быть получены через предложение RETURNING.

Примечание

Хотя событие InstanceEvents.refresh_flush() срабатывает как для объекта, который был INSERTed, так и для объекта, который был UPDATEd, это событие направлено в основном на процесс UPDATE; это в основном внутренний артефакт, что действия INSERT также могут вызвать это событие, и обратите внимание, что основные ключевые столбцы для строки INSERTed явно опущены из этого события. Для того чтобы перехватить состояние объекта, только что подвергшегося INSERT, лучше использовать SessionEvents.pending_to_persistent() и MapperEvents.after_insert().

Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • flush_context – Внутренний объект UOWTransaction, который обрабатывает детали промывки.

  • attrs – последовательность имен атрибутов, которые были заполнены.

method sqlalchemy.orm.InstanceEvents.unpickle(target: _O, state_dict: _InstanceDict) None

Получение экземпляра объекта после того, как связанное с ним состояние было распаковано.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass, 'unpickle')
def receive_unpickle(target, state_dict):
    "listen for the 'unpickle' event"

    # ... (event handling logic) ...
Параметры:
  • target – сопоставленный экземпляр. Если событие настроено с параметром raw=True, вместо него будет объект управления состоянием InstanceState, связанный с экземпляром.

  • state_dict – словарь, отправленный в __setstate__, содержащий словарь состояний, который был забран.

События атрибутов

События атрибутов запускаются по мере того, как что-то происходит с отдельными атрибутами объектов, сопоставленных с ORM. Эти события формируют основу для таких вещей, как custom validation functions, а также backref handlers.

Object Name Description

AttributeEvents

Определите события для атрибутов объекта.

class sqlalchemy.orm.AttributeEvents

Определите события для атрибутов объекта.

Обычно они определяются в дескрипторе привязки к классу для целевого класса.

Например, чтобы зарегистрировать слушателя, который будет получать событие AttributeEvents.append():

from sqlalchemy import event

@event.listens_for(MyClass.collection, 'append', propagate=True)
def my_append_listener(target, value, initiator):
    print("received append event for target: %s" % target)

Слушатели имеют возможность возвращать возможно измененную версию значения, когда флаг AttributeEvents.retval передается в listen() или listens_for(), как показано ниже, с использованием события AttributeEvents.set():

def validate_phone(target, value, oldvalue, initiator):
    "Strip non-numeric characters from a phone number"

    return re.sub(r'\D', '', value)

# setup listener on UserContact.phone attribute, instructing
# it to use the return value
listen(UserContact.phone, 'set', validate_phone, retval=True)

Функция проверки, подобная приведенной выше, может также вызвать исключение, такое как ValueError, чтобы остановить операцию.

Флаг AttributeEvents.propagate также важен при применении слушателей к сопоставленным классам, которые также имеют сопоставленные подклассы, как при использовании моделей наследования сопоставления:

@event.listens_for(MySuperClass.attr, 'set', propagate=True)
def receive_set(target, value, initiator):
    print("value set: %s" % target)

Полный список модификаторов, доступных для функций listen() и listens_for(), приведен ниже.

Параметры:
  • active_history=False – При значении True указывает, что событие «set» хотело бы получить «старое» значение, заменяемое безоговорочно, даже если для этого требуется загрузка базы данных. Обратите внимание, что active_history также может быть установлено непосредственно через column_property() и relationship().

  • propagate=False – При значении True функция слушателя будет установлена не только для заданного атрибута класса, но и для одноименных атрибутов всех текущих подклассов этого класса, а также всех будущих подклассов этого класса, используя дополнительный слушатель, который прослушивает события инструментации.

  • raw=False – При значении True «целевым» аргументом события будет объект управления InstanceState, а не сам сопоставленный экземпляр.

  • retval=False – когда True, пользовательская функция прослушивания события должна вернуть аргумент «значение» из функции. Это дает возможность функции прослушивания изменить значение, которое в конечном итоге используется для события «set» или «append».

Классная подпись

класс sqlalchemy.orm.AttributeEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.AttributeEvents.append(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) Optional[_T]

Получение события добавления коллекции.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'append')
def receive_append(target, value, initiator):
    "listen for the 'append' event"

    # ... (event handling logic) ...

Событие append вызывается для каждого элемента при добавлении его в коллекцию. Это происходит как при добавлении одного элемента, так и при операции «массовая замена».

Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – добавляемое значение. Если этот слушатель зарегистрирован в retval=True, функция слушателя должна вернуть это значение или новое значение, которое его заменяет.

  • initiator – Экземпляр Event, представляющий инициацию события. Может быть изменен по сравнению со своим первоначальным значением обработчиками обратных ссылок для управления цепным распространением события, а также может быть проверен на наличие информации об источнике события.

  • key – Когда событие устанавливается с помощью параметра AttributeEvents.include_key, установленного в True, это будет ключ, используемый в операции, например collection[some_key_or_index] = value. Параметр не передается в событие вообще, если AttributeEvents.include_key не был использован для установки события; это сделано для обеспечения обратной совместимости с существующими обработчиками событий, которые не включают параметр key. … версия добавлена:: 2.0

Результат:

если событие было зарегистрировано с помощью retval=True, должно быть возвращено заданное значение или новое эффективное значение.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

AttributeEvents.bulk_replace()

method sqlalchemy.orm.AttributeEvents.append_wo_mutation(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) None

Получение события добавления коллекции, когда коллекция на самом деле не была изменена.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'append_wo_mutation')
def receive_append_wo_mutation(target, value, initiator):
    "listen for the 'append_wo_mutation' event"

    # ... (event handling logic) ...

Это событие отличается от AttributeEvents.append() тем, что оно срабатывает при дедупликации коллекций, таких как множества и словари, когда объект уже существует в целевой коллекции. Событие не имеет возвращаемого значения, и идентичность данного объекта не может быть изменена.

Событие используется для каскадирования объектов в Session, когда коллекция уже была изменена через событие backref.

Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – значение, которое будет добавлено, если объект еще не существует в коллекции.

  • initiator – Экземпляр Event, представляющий инициацию события. Может быть изменен по сравнению со своим первоначальным значением обработчиками обратных ссылок для управления цепным распространением события, а также может быть проверен на наличие информации об источнике события.

  • key – Когда событие устанавливается с помощью параметра AttributeEvents.include_key, установленного в True, это будет ключ, используемый в операции, например collection[some_key_or_index] = value. Параметр не передается в событие вообще, если AttributeEvents.include_key не был использован для установки события; это сделано для обеспечения обратной совместимости с существующими обработчиками событий, которые не включают параметр key. … версия добавлена:: 2.0

Результат:

Для этого события не определено возвращаемое значение.

Добавлено в версии 1.4.15.

method sqlalchemy.orm.AttributeEvents.bulk_replace(target: _O, values: Iterable[_T], initiator: Event, *, keys: Optional[Iterable[EventConstants]] = None) None

Получение события «массовая замена» коллекции.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'bulk_replace')
def receive_bulk_replace(target, values, initiator):
    "listen for the 'bulk_replace' event"

    # ... (event handling logic) ...

Это событие вызывается для последовательности значений, когда они поступают в операцию набора коллекции, которая может быть изменена на месте до того, как значения будут обработаны как объекты ORM. Это «ранний крючок», который запускается до того, как процедура массовой замены попытается согласовать, какие объекты уже присутствуют в коллекции, а какие удаляются операцией чистой замены.

Обычно этот метод сочетается с использованием события AttributeEvents.append(). При использовании обоих этих событий обратите внимание, что операция массовой замены вызовет событие AttributeEvents.append() для всех новых элементов, даже после того, как AttributeEvents.bulk_replace() было вызвано для коллекции в целом. Чтобы определить, является ли событие AttributeEvents.append() частью массовой замены, используйте символ attributes.OP_BULK_REPLACE для проверки входящего инициатора:

from sqlalchemy.orm.attributes import OP_BULK_REPLACE

@event.listens_for(SomeObject.collection, "bulk_replace")
def process_collection(target, values, initiator):
    values[:] = [_make_value(value) for value in values]

@event.listens_for(SomeObject.collection, "append", retval=True)
def process_collection(target, value, initiator):
    # make sure bulk_replace didn't already do it
    if initiator is None or initiator.op is not OP_BULK_REPLACE:
        return _make_value(value)
    else:
        return value

Добавлено в версии 1.2.

Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – последовательность (например, список) устанавливаемых значений. Обработчик может изменять этот список на месте.

  • initiator – Экземпляр Event, представляющий инициацию события.

  • keys – Если событие устанавливается с помощью параметра AttributeEvents.include_key, установленного в True, это будет последовательность ключей, используемых в операции, обычно только для обновления словаря. Параметр вообще не передается событию, если для установки события не использовался параметр AttributeEvents.include_key; это делается для обеспечения обратной совместимости с существующими обработчиками событий, которые не включают параметр key. … версия добавлена:: 2.0

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

attribute sqlalchemy.orm.AttributeEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.AttributeEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

method sqlalchemy.orm.AttributeEvents.dispose_collection(target: _O, collection: Collection[Any], collection_adapter: CollectionAdapter) None

Получение события «утилизация коллекции».

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'dispose_collection')
def receive_dispose_collection(target, collection, collection_adapter):
    "listen for the 'dispose_collection' event"

    # ... (event handling logic) ...

Это событие срабатывает для атрибута на основе коллекции, когда коллекция заменяется, то есть:

u1.addresses.append(a1)

u1.addresses = [a2, a3]  # <- old collection is disposed

Полученная старая коллекция будет содержать прежнее содержимое.

Изменено в версии 1.2: Коллекция, переданная в AttributeEvents.dispose_collection(), теперь будет иметь свое содержимое перед dispose; ранее коллекция была пустой.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

method sqlalchemy.orm.AttributeEvents.init_collection(target: _O, collection: Type[Collection[Any]], collection_adapter: CollectionAdapter) None

Получение события „collection init“.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'init_collection')
def receive_init_collection(target, collection, collection_adapter):
    "listen for the 'init_collection' event"

    # ... (event handling logic) ...

Это событие запускается для атрибута на основе коллекции, когда впервые создается начальная «пустая коллекция» для пустого атрибута, а также когда коллекция заменяется на новую, например, через событие set.

Например, учитывая, что User.addresses является коллекцией, основанной на отношениях, событие срабатывает здесь:

u1 = User()
u1.addresses.append(a1)  #  <- new collection

а также во время операций по замене:

u1.addresses = [a2, a3]  #  <- new collection
Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • collection – новая коллекция. Она всегда будет формироваться из того, что было указано как relationship.collection_class, и всегда будет пустой.

  • collection_adapterCollectionAdapter, который будет опосредовать внутренний доступ к коллекции.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

AttributeEvents.init_scalar() - «скалярная» версия этого события.

method sqlalchemy.orm.AttributeEvents.init_scalar(target: _O, value: _T, dict_: Dict[Any, Any]) None

Получение скалярного события «init».

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'init_scalar')
def receive_init_scalar(target, value, dict_):
    "listen for the 'init_scalar' event"

    # ... (event handling logic) ...

Это событие вызывается при обращении к неинициализированному, неперсистированному скалярному атрибуту, например, read:

x = my_object.some_attribute

Поведение ORM по умолчанию, когда это происходит для неинициализированного атрибута, заключается в возвращении значения None; обратите внимание, что это отличается от обычного поведения Python, когда возвращается значение AttributeError. Событие здесь может быть использовано для настройки того, какое значение будет возвращено, с предположением, что слушатель события будет зеркально отражать генератор по умолчанию, настроенный на объект Core Column.

Поскольку генератор по умолчанию на Column может также выдавать изменяющееся значение, например, метку времени, обработчик события AttributeEvents.init_scalar() может также использоваться для установки нового возвращаемого значения, так что функция генерации по умолчанию на уровне Core срабатывает только один раз, но в момент обращения к атрибуту на неперсистентном объекте. Обычно при обращении к неинициализированному атрибуту состояние объекта не изменяется (в более старых версиях SQLAlchemy состояние объекта действительно изменялось).

Если генератор по умолчанию на столбце возвращает определенную константу, можно использовать обработчик следующим образом:

SOME_CONSTANT = 3.1415926

class MyClass(Base):
    # ...

    some_attribute = Column(Numeric, default=SOME_CONSTANT)

@event.listens_for(
    MyClass.some_attribute, "init_scalar",
    retval=True, propagate=True)
def _init_some_attribute(target, dict_, value):
    dict_['some_attribute'] = SOME_CONSTANT
    return SOME_CONSTANT

Выше мы инициализируем атрибут MyClass.some_attribute значением SOME_CONSTANT. Приведенный выше код включает следующие функции:

  • Устанавливая значение SOME_CONSTANT в данном dict_, мы указываем, что это значение должно быть сохранено в базе данных. Это заменяет использование SOME_CONSTANT в генераторе по умолчанию для Column. Пример active_column_defaults.py, приведенный в Инструментарий атрибутов, иллюстрирует использование того же подхода для изменяющегося значения по умолчанию, например, генератора временных меток. В этом конкретном примере нет строгой необходимости делать это, поскольку SOME_CONSTANT будет частью оператора INSERT в любом случае.

  • Установив флаг retval=True, значение, которое мы возвращаем из функции, будет возвращено геттером атрибута. Без этого флага событие воспринимается как пассивный наблюдатель, и возвращаемое значение нашей функции игнорируется.

  • Флаг propagate=True имеет значение, если отображаемый класс включает наследуемые подклассы, которые также будут использовать этот обработчик событий. Без этого флага наследуемый подкласс не будет использовать наш обработчик событий.

В приведенном выше примере событие набора атрибутов AttributeEvents.set(), а также связанная с ним функция проверки, предоставляемая validates, не вызываются, когда мы применяем наше значение к данному dict_. Чтобы эти события были вызваны в ответ на наше новое значение, примените значение к данному объекту как обычную операцию набора атрибутов:

SOME_CONSTANT = 3.1415926

@event.listens_for(
    MyClass.some_attribute, "init_scalar",
    retval=True, propagate=True)
def _init_some_attribute(target, dict_, value):
    # will also fire off attribute set events
    target.some_attribute = SOME_CONSTANT
    return SOME_CONSTANT

Когда установлено несколько слушателей, генерация значения «цепочкой» передается от одного слушателя к другому путем передачи значения, возвращаемого предыдущим слушателем, который определяет retval=True, в качестве аргумента value следующего слушателя.

Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – значение, которое должно быть возвращено до вызова этого обработчика событий. Это значение начинается как значение None, однако будет являться возвращаемым значением предыдущей функции обработчика события, если присутствует несколько слушателей.

  • dict_ – словарь атрибутов этого сопоставленного объекта. Обычно это __dict__ объекта, но во всех случаях представляет собой место назначения, которое система атрибутов использует для получения фактического значения этого атрибута. Помещение значения в этот словарь приводит к тому, что значение будет использовано в операторе INSERT, создаваемом блоком работы.

См.также

AttributeEvents.init_collection() - коллекционная версия этого события

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

Инструментарий атрибутов - см. пример active_column_defaults.py.

method sqlalchemy.orm.AttributeEvents.modified(target: _O, initiator: Event) None

Получите событие «изменено».

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'modified')
def receive_modified(target, initiator):
    "listen for the 'modified' event"

    # ... (event handling logic) ...

Это событие возникает, когда функция flag_modified() используется для запуска события модификации атрибута без установки какого-либо конкретного значения.

Добавлено в версии 1.2.

Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • initiator – Экземпляр Event, представляющий инициацию события.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

method sqlalchemy.orm.AttributeEvents.remove(target: _O, value: _T, initiator: Event, *, key: EventConstants = EventConstants.NO_KEY) None

Получение события удаления коллекции.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'remove')
def receive_remove(target, value, initiator):
    "listen for the 'remove' event"

    # ... (event handling logic) ...
Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – удаляемое значение.

  • initiator – Экземпляр Event, представляющий инициацию события. Может быть изменен по сравнению с исходным значением обработчиками обратных ссылок для управления цепным распространением событий.

  • key – Когда событие устанавливается с помощью параметра AttributeEvents.include_key, установленного в True, это будет ключ, используемый в операции, например del collection[some_key_or_index]. Параметр не передается в событие вообще, если AttributeEvents.include_key не был использован для установки события; это сделано для обеспечения обратной совместимости с существующими обработчиками событий, которые не включают параметр key. … версия добавлена:: 2.0

Результат:

Для этого события не определено возвращаемое значение.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

method sqlalchemy.orm.AttributeEvents.set(target: _O, value: _T, oldvalue: _T, initiator: Event) None

Получение события скалярного набора.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeClass.some_attribute, 'set')
def receive_set(target, value, oldvalue, initiator):
    "listen for the 'set' event"

    # ... (event handling logic) ...
Параметры:
  • target – экземпляр объекта, принимающего событие. Если слушатель зарегистрирован на raw=True, то это будет объект InstanceState.

  • value – устанавливаемое значение. Если этот слушатель зарегистрирован в retval=True, функция слушателя должна вернуть это значение или новое значение, которое его заменяет.

  • oldvalue – предыдущее заменяемое значение. Это также может быть символ NEVER_SET или NO_VALUE. Если слушатель зарегистрирован с помощью active_history=True, предыдущее значение атрибута будет загружено из базы данных, если существующее значение в данный момент выгружено или истекло.

  • initiator – Экземпляр Event, представляющий инициацию события. Может быть изменен по сравнению с исходным значением обработчиками обратных ссылок для управления цепным распространением событий.

Результат:

если событие было зарегистрировано с помощью retval=True, должно быть возвращено заданное значение или новое эффективное значение.

См.также

AttributeEvents - справочная информация об опциях слушателя, таких как распространение в подклассы.

События запроса

Object Name Description

QueryEvents

Представляют события в рамках построения объекта Query.

class sqlalchemy.orm.QueryEvents

Представляют события в рамках построения объекта Query.

Legacy Feature

Методы событий QueryEvents унаследованы от SQLAlchemy 2.0 и применяются только для прямого использования объекта Query. Они не используются для операторов 2.0 style. Для перехвата и модификации событий при использовании ORM в стиле 2.0 используйте хук SessionEvents.do_orm_execute().

Крючки QueryEvents теперь вытеснены крючком событий SessionEvents.do_orm_execute().

Классная подпись

класс sqlalchemy.orm.QueryEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.QueryEvents.before_compile(query: Query) None

Получение объекта Query перед его составлением в основной объект Select.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeQuery, 'before_compile')
def receive_before_compile(query):
    "listen for the 'before_compile' event"

    # ... (event handling logic) ...

Не рекомендуется, начиная с версии 1.4: Событие QueryEvents.before_compile() вытеснено гораздо более функциональным хуком SessionEvents.do_orm_execute(). В версии 1.4 событие QueryEvents.before_compile() больше не используется для загрузки атрибутов на уровне ORM, таких как загрузка отложенных или просроченных атрибутов, а также загрузчиков отношений. Смотрите новые примеры в События запросов ORM, которые иллюстрируют новые способы перехвата и модификации ORM-запросов для наиболее распространенной цели добавления произвольных критериев фильтрации.

Это событие предназначено для внесения изменений в запрос, заданный:

@event.listens_for(Query, "before_compile", retval=True)
def no_deleted(query):
    for desc in query.column_descriptions:
        if desc['type'] is User:
            entity = desc['entity']
            query = query.filter(entity.deleted == False)
    return query

Обычно событие следует прослушивать с установленным параметром retval=True, чтобы можно было вернуть измененный запрос.

Событие QueryEvents.before_compile() по умолчанию запрещает «запеченным» запросам кэшировать запрос, если крючок события возвращает новый объект Query. Это влияет как на прямое использование расширения запеченных запросов, так и на его работу в ленивых загрузчиках и нетерпеливых загрузчиках для отношений. Чтобы восстановить кэшируемый запрос, примените событие, добавив флаг bake_ok:

@event.listens_for(
    Query, "before_compile", retval=True, bake_ok=True)
def my_event(query):
    for desc in query.column_descriptions:
        if desc['type'] is User:
            entity = desc['entity']
            query = query.filter(entity.deleted == False)
    return query

Когда bake_ok имеет значение True, крючок событий будет вызван только один раз и не будет вызываться при последующих вызовах конкретного запроса, который кэшируется.

Добавлено в версии 1.3.11: - added the «bake_ok» flag to the QueryEvents.before_compile() event and disallowed caching via the «baked» extension from occurring for event handlers that return a new Query object if this flag is not set.

method sqlalchemy.orm.QueryEvents.before_compile_delete(query: Query, delete_context: BulkDelete) None

Разрешить модификацию объекта Query внутри Query.delete().

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeQuery, 'before_compile_delete')
def receive_before_compile_delete(query, delete_context):
    "listen for the 'before_compile_delete' event"

    # ... (event handling logic) ...

Не рекомендуется, начиная с версии 1.4: Событие QueryEvents.before_compile_delete() вытеснено гораздо более способным крючком SessionEvents.do_orm_execute().

Как и событие QueryEvents.before_compile(), это событие должно быть настроено с помощью retval=True, а возвращается измененный объект Query, как в

@event.listens_for(Query, "before_compile_delete", retval=True)
def no_deleted(query, delete_context):
    for desc in query.column_descriptions:
        if desc['type'] is User:
            entity = desc['entity']
            query = query.filter(entity.deleted == False)
    return query
Параметры:
  • query – экземпляр Query; это также атрибут .query данного объекта «delete context».

  • delete_context – объект «контекст удаления», который является объектом того же типа, что и описанный в QueryEvents.after_bulk_delete.delete_context.

Добавлено в версии 1.2.17.

method sqlalchemy.orm.QueryEvents.before_compile_update(query: Query, update_context: BulkUpdate) None

Разрешить модификацию объекта Query внутри Query.update().

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeQuery, 'before_compile_update')
def receive_before_compile_update(query, update_context):
    "listen for the 'before_compile_update' event"

    # ... (event handling logic) ...

Не рекомендуется, начиная с версии 1.4: Событие QueryEvents.before_compile_update() вытеснено гораздо более способным крючком SessionEvents.do_orm_execute().

Как и событие QueryEvents.before_compile(), если событие должно быть использовано для изменения объекта Query, оно должно быть настроено с помощью retval=True, а возвращен измененный объект Query, как в

@event.listens_for(Query, "before_compile_update", retval=True)
def no_deleted(query, update_context):
    for desc in query.column_descriptions:
        if desc['type'] is User:
            entity = desc['entity']
            query = query.filter(entity.deleted == False)

            update_context.values['timestamp'] = datetime.utcnow()
    return query

Словарь .values объекта «update context» также может быть изменен на месте, как показано выше.

Параметры:
  • query – экземпляр Query; это также атрибут .query данного объекта «update context».

  • update_context – объект «контекст обновления», который является объектом того же типа, что и описанный в QueryEvents.after_bulk_update.update_context. Объект имеет атрибут .values в контексте UPDATE, который является словарем параметров, переданных в Query.update(). Этот словарь может быть изменен для изменения пункта VALUES результирующего оператора UPDATE.

Добавлено в версии 1.2.17.

attribute sqlalchemy.orm.QueryEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.QueryEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

События в области приборостроения

Определяет систему инструментария классов SQLAlchemy.

Этот модуль обычно не виден непосредственно пользовательским приложениям, но определяет большую часть интерактивности ORM.

instrumentation.py занимается регистрацией классов конечных пользователей для отслеживания состояния. Он тесно взаимодействует с state.py и attributes.py, которые устанавливают инструментацию для каждого экземпляра и каждого класса-атрибута, соответственно.

Система инструментария класса может быть настроена для каждого класса или глобально с помощью модуля sqlalchemy.ext.instrumentation, который предоставляет средства для построения и задания альтернативных форм инструментария.

Object Name Description

InstrumentationEvents

События, связанные с событиями инструментария класса.

class sqlalchemy.orm.InstrumentationEvents

События, связанные с событиями инструментария класса.

Слушатели здесь поддерживают установку на любой новый класс стиля, то есть на любой объект, который является подклассом „type“. После этого будут запускаться события, связанные с этим классом. Если в event.listen() передан флаг «propagate=True», то событие будет отработано и для подклассов этого класса.

В качестве цели также принимается встроенный модуль Python type, который при использовании имеет эффект испускания событий для всех классов.

Обратите внимание, что флаг «распространять» здесь установлен по умолчанию True, в отличие от других событий на уровне классов, где он установлен по умолчанию False. Это означает, что новые подклассы также будут являться объектом этих событий, когда слушатель установлен на суперкласс.

Классная подпись

класс sqlalchemy.orm.InstrumentationEvents (sqlalchemy.event.Events)

method sqlalchemy.orm.InstrumentationEvents.attribute_instrument(cls: ClassManager[_O], key: _KT, inst: _O) None

Вызывается, когда атрибут инструментирован.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'attribute_instrument')
def receive_attribute_instrument(cls, key, inst):
    "listen for the 'attribute_instrument' event"

    # ... (event handling logic) ...
method sqlalchemy.orm.InstrumentationEvents.class_instrument(cls: ClassManager[_O]) None

Вызывается после инструментализации данного класса.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'class_instrument')
def receive_class_instrument(cls):
    "listen for the 'class_instrument' event"

    # ... (event handling logic) ...

Чтобы добраться до ClassManager, используйте manager_of_class().

method sqlalchemy.orm.InstrumentationEvents.class_uninstrument(cls: ClassManager[_O]) None

Вызывается перед тем, как данный класс будет разгруппирован.

Примерные формы аргументов:

from sqlalchemy import event


@event.listens_for(SomeBaseClass, 'class_uninstrument')
def receive_class_uninstrument(cls):
    "listen for the 'class_uninstrument' event"

    # ... (event handling logic) ...

Чтобы добраться до ClassManager, используйте manager_of_class().

attribute sqlalchemy.orm.InstrumentationEvents.dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.InstrumentationEventsDispatch object>

ссылку обратно на класс _Dispatch.

Двунаправленный против _Dispatch._events

Вернуться на верх