SqlAlchemy 2.0 中文文档(二十六)(1)

简介: SqlAlchemy 2.0 中文文档(二十六)


原文:docs.sqlalchemy.org/en/20/contents.html

事件和内部

原文:docs.sqlalchemy.org/en/20/orm/extending.html

SQLAlchemy ORM 以及 Core 通常通过事件钩子进行扩展。请务必查看事件系统的使用。

  • ORM 事件
  • 会话事件
  • 映射器事件
  • 实例事件
  • 属性事件
  • 查询事件
  • 仪器事件
  • ORM 内部
  • AttributeState
  • CascadeOptions
  • ClassManager
  • ColumnProperty
  • Composite
  • CompositeProperty
  • AttributeEventToken
  • IdentityMap
  • InspectionAttr
  • InspectionAttrInfo
  • InstanceState
  • InstrumentedAttribute
  • LoaderCallableStatus
  • Mapped
  • MappedColumn
  • MapperProperty
  • MappedSQLExpression
  • InspectionAttrExtensionType
  • NotExtension
  • merge_result()
  • merge_frozen_result()
  • PropComparator
  • Relationship
  • RelationshipDirection
  • RelationshipProperty
  • SQLORMExpression
  • Synonym
  • SynonymProperty
  • QueryContext
  • QueryableAttribute
  • UOWTransaction
  • ORM 异常
  • ConcurrentModificationError
  • DetachedInstanceError
  • FlushError
  • LoaderStrategyException
  • NO_STATE
  • ObjectDeletedError
  • ObjectDereferencedError
  • StaleDataError
  • UnmappedClassError
  • UnmappedColumnError
  • UnmappedError
  • UnmappedInstanceError

ORM 事件

原文:docs.sqlalchemy.org/en/20/orm/events.html

ORM 包括各种可供订阅的钩子。

要了解最常用的 ORM 事件的介绍,请参阅使用事件跟踪查询、对象和会话更改部分。一般讨论事件系统,请参阅事件。关于连接和低级语句执行等非 ORM 事件的描述,请参阅核心事件。

会话事件

最基本的事件钩子可在 ORM Session对象级别使用。这里拦截的内容包括:

  • 持久化操作 - 将更改发送到数据库的 ORM 刷新过程可以使用在刷新的不同部分触发的事件进行扩展,以增强或修改发送到数据库的数据,或者在持久化发生时允许其他事情发生。在持久化事件中了解更多信息。
  • 对象生命周期事件 - 当对象被添加、持久化、从会话中删除时触发的钩子。在对象生命周期事件中了解更多信息。
  • 执行事件 - 2.0 风格执行模型的一部分,拦截所有针对 ORM 实体的 SELECT 语句,以及在刷新过程之外的批量 UPDATE 和 DELETE 语句,使用Session.execute()方法通过SessionEvents.do_orm_execute()方法。在执行事件中了解更多关于此事件的信息。

请务必阅读使用事件跟踪查询、对象和会话更改章节,以了解这些事件的背景。

对象名称 描述
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管理对象,而不是映射的实例本身。
    版本 1.3.14 中的新功能。
  • restore_load_context=False
    适用于SessionEvents.loaded_as_persistent()事件。在事件钩子完成时恢复对象的加载器上下文,以便正在进行的急切加载操作继续正确地针对对象。如果在此事件中将对象移动到新的加载器上下文而未设置此标志,则会发出警告。
    版本 1.3.14 中的新功能。

成员

after_attach(), after_begin(), after_bulk_delete(),  after_bulk_update(), after_commit(), after_flush(),  after_flush_postexec(), after_rollback(), after_soft_rollback(),  after_transaction_create(), after_transaction_end(), before_attach(),  before_commit(), before_flush(), deleted_to_detached(),  deleted_to_persistent(), detached_to_persistent(), dispatch,  do_orm_execute(), loaded_as_persistent(), pending_to_persistent(),  pending_to_transient(), persistent_to_deleted(),  persistent_to_detached(), persistent_to_transient(),  transient_to_pending()

类签名

sqlalchemy.orm.SessionEventssqlalchemy.event.Events

method 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()事件。

另请参阅

SessionEvents.before_attach()

对象生命周期事件

method 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修改其自身内部状态的过程中调用。要在此挂钩内调用 SQL 操作,请使用事件提供的Connection;请勿直接使用Session运行 SQL 操作。

参数:

  • session – 目标Session
  • transactionSessionTransaction
  • connection – 将用于 SQL 语句的Connection对象。

另请参阅

SessionEvents.before_commit()

SessionEvents.after_commit()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

method 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。将来的版本中将删除接受上述“已弃用”参数签名的监听器函数的支持。

遗留特性

SessionEvents.after_bulk_delete()方法是 SQLAlchemy 2.0 的传统事件钩子。该事件不参与使用delete()在 ORM UPDATE and DELETE with Custom WHERE Criteria 中记录的 2.0 风格调用。对于 2.0 风格的使用,SessionEvents.do_orm_execute()钩子将拦截这些调用。

参数:

delete_context -

一个包含有关更新的“删除上下文”对象,包括这些属性:

  • session - 涉及的Session

  • query - 调用此更新操作的Query对象。

  • result 作为批量 DELETE 操作的结果返回的CursorResult

从版本 1.4 开始更改:update_context 不再与QueryContext对象相关联。

另请参阅

QueryEvents.before_compile_delete()

SessionEvents.after_bulk_update()

method 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。将来的版本中将删除接受上述“已弃用”参数签名的监听器函数的支持。

遗留特性

SessionEvents.after_bulk_update()方法是 SQLAlchemy 2.0 版本之后的传统事件钩子。该事件不参与使用update()进行的 2.0 风格调用,该调用在 ORM UPDATE and DELETE with Custom WHERE Criteria 中有记录。对于 2.0 风格的使用,SessionEvents.do_orm_execute()钩子将拦截这些调用。

参数:

update_context

包含有关更新的“更新上下文”对象,包括这些属性:

  • session - 涉及的Session

  • query -调用此更新操作的Query对象。

  • values 传递给Query.update()的“值”字典。

  • result 作为批量更新操作的结果返回的CursorResult

从 1.4 版本开始更改:update_context 不再与QueryContext对象关联。

另请参阅

QueryEvents.before_compile_update()

SessionEvents.after_bulk_delete()

method 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()钩子不是每次刷新一次,也就是说,Session可以在事务范围内多次向数据库发出 SQL。要拦截这些事件,请使用SessionEvents.before_flush()SessionEvents.after_flush()SessionEvents.after_flush_postexec()事件。

注意

当调用SessionEvents.after_commit()事件时,Session处于非活动事务状态,因此无法发出 SQL。若要发出与每个事务对应的 SQL,请使用SessionEvents.before_commit()事件。

参数:

session – 目标Session

另请参阅

SessionEvents.before_commit()

SessionEvents.after_begin()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

method after_flush(session: Session, flush_context: UOWTransaction) → None

在刷新完成后执行,但在调用提交之前执行。

示例参数形式:

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对象。

另请参阅

SessionEvents.before_flush()

SessionEvents.after_flush_postexec()

持久性事件

method after_flush_postexec(session: Session, flush_context: UOWTransaction) → None

在刷新完成后执行,并在后执行状态发生后执行。

示例参数形式:

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’列表处于最终状态的时刻。实际是否提交()取决于刷新是否启动了自己的事务或参与了较大事务。

参数:

  • session – 目标 Session
  • flush_context – 处理刷新细节的内部UOWTransaction 对象。

另请参阅

SessionEvents.before_flush()

SessionEvents.after_flush()

持久性事件

method 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) ...

请注意,此事件仅在实际数据库回滚发生时触发 - 当底层 DBAPI 事务已经回滚时,并不会在每次调用 Session.rollback() 方法时触发。在许多情况下,在此事件期间,Session 不会处于“活动”状态,因为当前事务无效。要获取在最外层回滚已经执行后处于活动状态的 Session,请使用 SessionEvents.after_soft_rollback() 事件,并检查 Session.is_active 标志。

参数:

session – 目标 Session

method 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 可以在外部回滚后通过首先检查 Session.is_active 标志来调用 SQL 和 Session.query() 操作。

@event.listens_for(Session, "after_soft_rollback")
def do_something(session, previous_transaction):
    if session.is_active:
        session.execute(text("select * from some_table"))

参数:

  • session – 目标Session
  • previous_transaction – 刚关闭的SessionTransaction事务标记对象。给定Session的当前SessionTransaction可通过Session.transaction属性获得。
method 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:
        # work with top-level transaction
  • 要检测SessionTransaction是否为 SAVEPOINT,请使用SessionTransaction.nested属性:
@event.listens_for(session, "after_transaction_create")
def after_transaction_create(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction

另请参阅

SessionTransaction

SessionEvents.after_transaction_end()

method 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:
        # work with top-level transaction
  • 要检测SessionTransaction是否为 SAVEPOINT,请使用SessionTransaction.nested属性:
@event.listens_for(session, "after_transaction_create")
def after_transaction_end(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction

另请参见

SessionTransaction

SessionEvents.after_transaction_create()

method 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) ...

这在添加、删除或合并导致对象成为会话的一部分之前被调用。

另请参见

SessionEvents.after_attach()

对象生命周期事件

method before_commit(session: Session) → None

在提交之前执行。

示例参数形式:

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()挂钩是每次刷新一次,也就是说,在事务范围内,Session可以多次向数据库发出 SQL。要拦截这些事件,请使用SessionEvents.before_flush()SessionEvents.after_flush()SessionEvents.after_flush_postexec()事件。

参数:

session – 目标Session

另请参阅

SessionEvents.after_commit()

SessionEvents.after_begin()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

method before_flush(session: Session, flush_context: UOWTransaction, instances: Sequence[_O] | None) → 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()方法的对象集合(请注意,此用法已被弃用)。

另请参阅

SessionEvents.after_flush()

SessionEvents.after_flush_postexec()

持久性事件

method 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的事务被提交时;对象从被删除状态转移到分离状态。

当在调用Session.expunge_all()Session.close()事件时,以及如果对象通过Session.expunge()从其删除状态单独清除时,也会为在刷新时被删除的对象调用。

另请参阅

对象生命周期事件

method deleted_to_persistent(session: Session, instance: _O) → None

拦截特定对象的“删除到持久化”转换。

示例参数形式:

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 detached_to_persistent(session: Session, instance: _O) → None

拦截特定对象的“分离到持久”转换。

示例参数形式:

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 不相关联的情况下调用 Session.delete() 调用(请注意,将对象标记为“已删除”在刷新进行之前仍保持“持久”状态)。

注意

如果对象在调用 Session.delete() 的过程中变为持久对象,则在调用此事件时对象尚未标记为已删除。要检测已删除的对象,请在刷新进行后检查发送到 SessionEvents.persistent_to_detached() 事件的 deleted 标志,或者如果需要在刷新之前拦截已删除的对象,则在 SessionEvents.before_flush() 事件中检查 Session.deleted 集合。

参数:

  • session – 目标 Session
  • instance – 正在操作的 ORM 映射实例。

另请参阅

对象生命周期事件

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

参考 _Dispatch 类。

双向与 _Dispatch._events

method 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) ...

此事件适用于从Session.execute()方法以及相关方法如Session.scalars()Session.scalar()调用的所有顶级 SQL 语句。从 SQLAlchemy 1.4 开始,通过Session.execute()方法以及相关方法Session.scalars()Session.scalar()等运行的所有 ORM 查询都将参与此事件。此事件钩子适用于在 ORM 刷新过程内部发出的查询,即在刷新中描述的过程。

注意

SessionEvents.do_orm_execute() 事件钩子仅在ORM 语句执行时触发,意味着仅对通过Session.execute()等方法在Session对象上调用的语句触发。它适用于仅由 SQLAlchemy Core 调用的语句,即通过Connection.execute()直接调用或由Engine对象发起而不涉及任何Session的语句。要拦截所有SQL 执行,无论是否使用 Core 或 ORM API,请参阅ConnectionEvents中的事件钩子,例如ConnectionEvents.before_execute()ConnectionEvents.before_cursor_execute()

此事件钩子也适用于在 ORM 刷新过程内部发出的查询,即在刷新中描述的过程;要拦截刷新过程中的步骤,请参阅 Persistence Events 以及 Mapper-level Flush Events 中描述的事件钩子。

此事件是一个do_事件,意味着它具有替换Session.execute()方法通常执行的操作的能力。这包括分片和结果缓存方案,这些方案可能希望在多个数据库连接上调用相同的语句,返回从每个连接合并的结果,或者根本不调用该语句,而是从缓存返回数据。

该钩子旨在替换在 SQLAlchemy 1.4 之前可以被子类化的Query._execute_and_instances方法的使用。

参数:

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()事件钩子。

水平分片 - 水平分片示例/扩展依赖于SessionEvents.do_orm_execute()事件钩子,在多个后端上调用 SQL 语句并返回合并结果。

1.4 版中的新功能。

method 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 pending_to_persistent(session: Session, instance: _O) → None

拦截特定对象的“待定到持久”的转换。

示例参数形式:

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) ...

此事件在刷新过程中调用,类似于扫描Session.new集合在SessionEvents.after_flush()事件中。但是,在这种情况下,当调用事件时,对象已经被移动到持久状态。

参数:

  • session – 目标Session
  • instance – 正在操作的 ORM 映射实例。

另请参阅

对象生命周期事件

method 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 persistent_to_deleted(session: Session, instance: _O) → None

拦截特定对象的“持久到已删除”转换。

示例参数形式:

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) ...

当在 flush 过程中从数据库中删除持久化对象的标识时,会触发此事件,但是对象仍然与Session相关联,直到事务完成。

如果事务回滚,则对象再次转移到持久状态,并调用 SessionEvents.deleted_to_persistent() 事件。如果事务提交,则对象变为分离状态,这将触发 SessionEvents.deleted_to_detached() 事件。

请注意,虽然 Session.delete() 方法是将对象标记为已删除的主要公共接口,但由于级联规则的存在,许多对象会因级联规则而被删除,这些规则直到 flush 时才确定。因此,在 flush 进行之前,没有办法捕获每个将要删除的对象。因此,在 flush 结束时会调用 SessionEvents.persistent_to_deleted() 事件。

另请参见

对象生命周期事件

method persistent_to_detached(session: Session, instance: _O) → None

拦截特定对象的“持久到分离”转换。

示例参数形式:

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() 等方法
  • 在对象属于该会话事务的 INSERT 语句的一部分时,调用 Session.rollback() 方法

参数:

  • session – 目标 Session
  • instance – 正在操作的 ORM 映射实例。
  • deleted – 布尔值。如果为 True,则表示此对象因标记为已删除并被 flush 而转移到分离状态。

另请参见

对象生命周期事件

method 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 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())形成对比,因为它们在刷新过程中以每个对象为基础发生;虽然对象上的更细粒度的活动更为直接,但 Session 功能的可用性有限。
  • Mapper 配置事件 - 另一个主要的映射器钩子类别是在类被映射时发生的事件,当映射器被完成时以及当映射器集合被配置为相互引用时。这些事件包括 MapperEvents.instrument_class()MapperEvents.before_mapper_configured()MapperEvents.mapper_configured() 在单个 Mapper 级别,以及 MapperEvents.before_configured()MapperEvents.after_configured() 在一组 Mapper 对象的级别。
对象名称 描述
MapperEvents 定义特定于映射的事件。
class sqlalchemy.orm.MapperEvents

定义特定于映射的事件。

例如(e.g.):

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)

可用的目标包括:

  • 映射的类(mapped classes)
  • 已映射或待映射类的未映射超类(使用 propagate=True 标志)
  • Mapper 对象
  • Mapper 类本身指示监听所有映射器。

映射器事件提供了对映射器的关键部分的钩子,包括与对象工具、对象加载和对象持久性相关的部分。特别是,持久性方法 MapperEvents.before_insert()MapperEvents.before_update() 是增强正在持久化状态的流行位置 - 但是,这些方法在几个重要限制下运行。鼓励用户评估 SessionEvents.before_flush()SessionEvents.after_flush() 方法,作为更灵活和用户友好的挂钩,在刷新期间应用额外的数据库状态。

在使用 MapperEvents 时,listen() 函数提供了几个修饰符。

参数(Parameters):

  • propagate=False – 当为 True 时,事件监听器应应用于所有继承映射器和/或继承类的映射器,以及任何作为此监听器目标的映射器。
  • raw=False – 当为 True 时,传递给适用事件监听器函数的“target”参数将是实例的InstanceState管理对象,而不是映射实例本身。
  • retval=False –当为 True 时,用户定义的事件函数必须具有返回值,其目的是控制后续事件传播,或以其他方式通过映射器改变正在进行的操作。可能的返回值包括:
  • sqlalchemy.orm.interfaces.EXT_CONTINUE - 正常继续事件处理。
  • sqlalchemy.orm.interfaces.EXT_STOP - 取消链中所有后续事件处理程序。
  • 其他值 - 特定监听器指定的返回值。

成员

after_configured(), after_delete(), after_insert(),  after_mapper_constructed(), after_update(), before_configured(),  before_delete(), before_insert(), before_mapper_configured(),  before_update(), dispatch, instrument_class(), mapper_configured()

类签名

sqlalchemy.orm.MapperEvents (sqlalchemy.event.Events)

method 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():
    # ...

另请参见

MapperEvents.before_mapper_configured()

MapperEvents.mapper_configured()

MapperEvents.before_configured()

method 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) ...

注意

此事件适用于会话刷新操作,适用于 ORM-启用的 INSERT、UPDATE 和 DELETE 语句中描述的 ORM DML 操作。要拦截 ORM DML 事件,请使用SessionEvents.do_orm_execute()

此事件用于在给定连接上发出额外的 SQL 语句,以及执行与删除事件相关的应用程序特定的簿记。

该事件通常在一批相同类的对象的 DELETE 语句在先前步骤中一次性发出后被调用。

警告

映射级刷新事件仅允许对仅限于操作的行本地属性进行非常有限的操作,同时允许在给定的Connection上发出任何 SQL。请完整阅读映射级刷新事件中关于使用这些方法的指南;通常,应优先使用SessionEvents.before_flush()方法进行一般性的刷新更改。

参数:

  • mapper – 此事件的目标Mapper
  • connection – 用于为此实例发出 DELETE 语句的Connection。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
  • target – 被删除的映射实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。

返回:

此事件不支持返回值。

另请参阅

持久性事件

method 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) ...

注意

此事件适用于会话刷新操作,适用于描述在 ORM-启用的 INSERT、UPDATE 和 DELETE 语句中的 ORM DML 操作。要拦截 ORM DML 事件,请使用SessionEvents.do_orm_execute()

此事件用于修改实例发生 INSERT 后的仅 Python 状态,并在给定连接上发出附加的 SQL 语句。

在先前步骤中一次性发出它们的 INSERT 语句后,通常会为同一类的一批对象调用此事件。在极为罕见的情况下,如果这不是理想的情况,可以使用batch=False配置Mapper对象,这将导致实例批次被拆分为单个(性能较差)事件->持久化->事件步骤。

警告

仅允许在映射器级别刷新事件上执行非常有限的操作,仅限于对正在操作的行本地属性的操作,并允许在给定的Connection上发出任何 SQL。请完全阅读映射器级刷新事件中的注意事项,以获取有关使用这些方法的指南;通常,应优先使用SessionEvents.before_flush()方法进行一般刷新更改。

参数:

  • mapper – 此事件的目标Mapper
  • connection – 用于为此实例发出 INSERT 语句的Connection。这提供了一个句柄到目标数据库上的当前事务,该事务特定于此实例。
  • target – 正在持久化的映射实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。

返回:

此事件不支持返回值。

另请参阅

持久性事件

method 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 时创建其他映射类的处理程序的事件,这些映射类将在下次运行 registry.configure() 时成为同一配置步骤的一部分。

版本 2.0.2 中的新功能。

另请参阅

对象版本控制 - 一个示例,说明使用 MapperEvents.before_mapper_configured() 事件创建新的映射器以记录对象的更改审计历史。

method 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) ...

注意

此事件适用于 会话刷新操作,并且适用于在 ORM-Enabled INSERT、UPDATE 和 DELETE 语句 中描述的 ORM DML 操作。要拦截 ORM DML 事件,请使用 SessionEvents.do_orm_execute()

此事件用于在发生 UPDATE 后修改仅在 Python 中的实例状态,以及在给定连接上发出额外的 SQL 语句。

此方法对所有标记为“脏”的实例进行调用,甚至对其列基属性没有净变化 的实例,并且没有进行 UPDATE 语句。当任何列基属性的“设置属性”操作被调用或任何集合被修改时,对象被标记为脏。如果在更新时,没有列基属性有任何净变化,将不会发出 UPDATE 语句。这意味着发送到 MapperEvents.after_update() 的实例保证已发出 UPDATE 语句。

要检测对象上基于列的属性是否有净变化,并因此导致 UPDATE 语句,请使用 object_session(instance).is_modified(instance, include_collections=False)

该事件通常在一系列相同类的对象的 UPDATE 语句一次性发出之后被调用。在极少数情况下,如果这不是期望的情况,那么可以将 Mapper 配置为 batch=False,这将导致实例批次被拆分为单个(性能较差)的事件->持久化->事件步骤。

警告

映射器级别的刷新事件仅允许对仅限于正在操作的行的属性执行非常有限的操作,以及允许在给定的 Connection 上发出任何 SQL。请完全阅读 映射器级刷新事件 备注中关于使用这些方法的指导原则;通常,应优先考虑使用 SessionEvents.before_flush() 方法进行通用刷新更改。

参数:

  • mapper – 此事件的目标 Mapper
  • connection – 用于为此实例发出 UPDATE 语句的 Connection。这提供了一个句柄到当前事务的目标数据库,特定于这个实例。
  • target – 正在持久化的映射实例。如果事件配置为 raw=True,那么这将是与实例相关联的 InstanceState 状态管理对象。

返回值:

此事件不支持返回值。

另请参阅

持久化事件

method 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() 函数时被调用,在该函数执行任何工作之前。

此事件可应用于 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():
    ...

另请参阅

MapperEvents.before_mapper_configured()

MapperEvents.mapper_configured()

MapperEvents.after_configured()

method 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) ...

注意

此事件适用于会话刷新操作,不适用于描述在 ORM 启用的 INSERT、UPDATE 和 DELETE 语句中的 ORM DML 操作。要拦截 ORM DML 事件,请使用 SessionEvents.do_orm_execute()

此事件用于在给定连接上发出附加的 SQL 语句,以及执行与删除事件相关的应用程序特定簿记。

在后续步骤中一次性发出一批相同类别对象的 DELETE 语句之前,通常会为这个事件调用一次。

警告

映射器级刷新事件仅允许对仅针对正在操作的行的属性进行非常有限的操作,以及允许在给定的 Connection 上发出任何 SQL。请务必完整阅读 映射器级刷新事件 中的注释,以获取有关使用这些方法的指导;通常情况下,应首选 SessionEvents.before_flush() 方法进行一般性的刷新更改。

参数:

  • mapper – 此事件的目标Mapper
  • connection – 用于为此实例发出 DELETE 语句的Connection。这提供了一个句柄到当前事务的目标数据库,特定于此实例。
  • target – 正在删除的映射实例。如果事件配置为raw=True,则这将是与实例相关联的InstanceState状态管理对象。

返回:

此事件不支持返回值。

请参阅

持久性事件

method 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) ...

注意

此事件仅适用于会话刷新操作,并不适用于描述在 ORM 启用的 INSERT、UPDATE 和 DELETE 语句中的 ORM DML 操作。要拦截 ORM DML 事件,请使用SessionEvents.do_orm_execute()

此事件用于修改实例之前的本地、非对象相关属性,并在给定的连接上发出附加 SQL 语句。

在稍后的步骤中,通常会为同一类对象的一批对象调用此事件,然后在一次性发出它们的 INSERT 语句之前。在极少数情况下,如果这不是所需的,可以使用Mapper对象配置batch=False,这将导致实例的批处理被分解为单个(性能较差的)事件->持久性->事件步骤。

警告

Mapper 级别的刷新事件仅允许非常有限的操作,仅限于操作中的行本地属性,并允许在给定的Connection上发出任何 SQL。请完全阅读Mapper 级别的刷新事件中的注意事项,以获取使用这些方法的指南;通常,应优先考虑SessionEvents.before_flush()方法进行刷新时的一般更改。

参数:

  • mapper – 此事件的目标Mapper
  • connection – 用于为此实例发出 INSERT 语句的Connection。这提供了一个句柄进入目标数据库上的当前事务,特定于此实例。
  • target – 正在持久化的映射实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。

返回:

此事件不支持返回值。

另请参见

持久性事件

method 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()函数,以继续尝试配置所有可用的映射器。

与其他配置级别事件相比,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

另请参见

MapperEvents.before_configured()

MapperEvents.after_configured()

MapperEvents.mapper_configured()

method 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) ...

注意

此事件适用于会话刷新操作,适用于在 ORM-启用的 INSERT、UPDATE 和 DELETE 语句中描述的 ORM DML 操作。要拦截 ORM DML 事件,请使用SessionEvents.do_orm_execute()

此事件用于在更新发生之前修改实例上的本地、与对象无关的属性,以及在给定连接上发出附加的 SQL 语句。

此方法将为所有标记为“脏”的实例调用,即使它们的基于列的属性没有净变化。当对其基于列的属性之一调用“设置属性”操作或修改其任何集合时,对象将被标记为脏。如果在更新时,没有基于列的属性有任何净变化,将不会发出 UPDATE 语句。这意味着将发送到MapperEvents.before_update()的实例保证会发出 UPDATE 语句,尽管您可以通过修改属性以存在值的净变化来影响结果。

要检测对象上的基于列的属性是否有净变化,并因此生成 UPDATE 语句,请使用 object_session(instance).is_modified(instance, include_collections=False)

在稍后的步骤中,通常会一次调用相同类的一批对象的此事件,然后发出它们的 UPDATE 语句。在极其罕见的情况下,如果这不是理想的情况,可以将Mapper配置为 batch=False,这将导致将实例批处理为单个(并且性能更差)事件->持久化->事件步骤。

警告

映射器级刷新事件仅允许对仅限于正在操作的行的属性进行非常有限的操作,同时允许在给定的Connection上发出任何 SQL。 请务必阅读映射器级刷新事件中的注意事项,以获取有关使用这些方法的指导;一般来说,应优先考虑SessionEvents.before_flush()方法进行通用刷新更改。

参数:

  • mapper – 此事件的目标Mapper
  • connection – 用于为此实例发出 UPDATE 语句的Connection。这为当前事务提供了一个句柄,该事务针对与此实例特定相关的目标数据库。
  • target – 正在持久化的映射实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。

返回:

此事件不支持返回值。

另请参阅:

持久化事件

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

回溯到 _Dispatch 类。

双向关联到 _Dispatch._events

method 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_):
    " ... "

参数:

  • mapper – 此事件的目标是Mapper
  • class_ – 映射类。

另请参阅:

MapperEvents.after_mapper_constructed()

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_ – 映射类。

另请参阅

MapperEvents.before_configured()

MapperEvents.after_configured()

MapperEvents.before_mapper_configured()


SqlAlchemy 2.0 中文文档(二十六)(2)https://developer.aliyun.com/article/1560473

相关文章
|
4月前
|
SQL 数据库 Python
SqlAlchemy 2.0 中文文档(二十六)(4)
SqlAlchemy 2.0 中文文档(二十六)
66 2
|
4月前
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十二)(3)
SqlAlchemy 2.0 中文文档(二十二)
25 5
|
4月前
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十二)(2)
SqlAlchemy 2.0 中文文档(二十二)
43 3
|
4月前
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十六)(3)
SqlAlchemy 2.0 中文文档(二十六)
41 2
|
4月前
|
自然语言处理 数据库 Python
SqlAlchemy 2.0 中文文档(二十六)(2)
SqlAlchemy 2.0 中文文档(二十六)
31 2
|
4月前
|
SQL 前端开发 关系型数据库
SqlAlchemy 2.0 中文文档(二十七)(2)
SqlAlchemy 2.0 中文文档(二十七)
33 2
|
4月前
|
SQL 缓存 前端开发
SqlAlchemy 2.0 中文文档(二十七)(5)
SqlAlchemy 2.0 中文文档(二十七)
45 2
|
4月前
|
SQL 存储 数据库连接
SqlAlchemy 2.0 中文文档(二十二)(1)
SqlAlchemy 2.0 中文文档(二十二)
53 2
|
4月前
|
缓存 自然语言处理 数据库
SqlAlchemy 2.0 中文文档(二十六)(5)
SqlAlchemy 2.0 中文文档(二十六)
38 1
|
4月前
|
SQL 前端开发 API
SqlAlchemy 2.0 中文文档(二十七)(1)
SqlAlchemy 2.0 中文文档(二十七)
50 1