ORM 事件


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


有关最常用的 ORM 事件的介绍,请参阅该部分 使用 Events 跟踪查询、对象和 Session 更改。事件系统一般在 事件 中讨论。非 ORM 事件(例如有关连接和低级语句执行的事件)在 Core Events 中进行了介绍。


会话事件


最基本的事件钩子在 ORM 级别可用 Session 对象。此处拦截的内容类型包括:


  • 持久化作 - 可以使用在刷新的不同部分触发的事件来扩展向数据库发送更改的 ORM 刷新过程,以增强或修改发送到数据库的数据,或者允许在发生持久化时发生其他事情。在 Persistence Events 中阅读有关持久性事件的更多信息。


  • 对象生命周期事件 - 添加、持久保存、 从会话中删除。 阅读更多相关信息 对象生命周期事件


  • 执行事件 - 作为 2.0 风格执行模型的一部分,所有针对发出的 ORM 实体的 SELECT 语句,以及 flush 进程之外的批量 UPDATE 和 DELETE 语句,都使用 SessionEvents.do_orm_execute() 方法。在 Execute Events 中阅读有关此事件的更多信息。


请务必阅读 跟踪查询、对象和会话更改与事件 章节,了解这些事件的上下文。


对象名称

描述


会话事件


定义特定于 Session 生命周期的事件。


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=错误


    适用于 SessionEvents.loaded_as_persistent() 事件。当事件钩子完成时,恢复对象的加载程序上下文,以便正在进行的 Eager Load作继续适当地以对象为目标。如果未设置此标志,则如果对象从此事件中移动到新的 loader 上下文,则会发出警告。


    在 1.3.14 版本加入.


类签名


sqlalchemy.orm.SessionEventssqlalchemy.event.Events


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_attachsession Sessioninstance _O


在实例附加到会话后执行。


参数形式示例:

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


这是在 add、delete 或 merge 之后调用的。


注意


从 0.8 开始,此事件在项目与 session 完全关联触发,这与以前的版本不同。对于要求对象尚未成为会话状态一部分的事件处理程序(例如,在目标对象尚未完成时可能会自动刷新的处理程序),请考虑新的 before_attach() 事件。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_beginsession Sessiontransaction SessionTransactionconnection Connection


在连接上开始事务后执行。


参数形式示例:

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 修改自己的内部状态。 要在此 hook 中调用 SQL作,请使用 为活动提供的联系;不要使用 Session 运行 SQL作 径直。


参数

方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_bulk_deletedelete_context: _O


调用旧版 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()2.0 样式调用,记录在 具有自定义 WHERE 条件的 ORM UPDATE 和 DELETE。对于 2.0 样式的使用, SessionEvents.do_orm_execute() 钩子将拦截这些调用。


参数

delete_context


一个 “delete context” 对象,其中包含有关更新的详细信息,包括以下属性:


  • session - 涉及的 Session


  • query - 查询 对象,此更新作 被召唤。


  • resultCursorResult 由于 批量 DELETE作。


在 1.4 版本发生变更: update_context 不再具有 QueryContext 对象。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_bulk_updateupdate_context _O


调用旧版 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 样式调用 具有自定义 WHERE 条件的 ORM UPDATE 和 DELETE。对于 2.0 样式的使用, SessionEvents.do_orm_execute() 钩子将拦截这些调用。


参数

update_context


一个 “Update Context” 对象,其中包含有关更新的详细信息,包括以下属性:


在 1.4 版本发生变更: update_context 不再具有 QueryContext 对象。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_commitsession Session


在提交发生后执行。


参数形式示例:

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


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_flushsession Sessionflush_context: UOWTransaction


在 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作(例如相关项目的加载)可能会生成新的身份映射条目,这些条目将立即被替换,有时会导致令人困惑的结果。SQLAlchemy 将从版本 1.3.9 开始针对此情况发出警告。


参数

方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_flush_postexecsession Sessionflush_context: UOWTransaction


在 flush 完成后和 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 是启动自己的事务还是参与更大的事务。


参数

方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_rollbacksession Session


在发生实际 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 在此事件期间不会处于 “active” 状态,因为当前交易无效。获取会话 在最外层回滚进行后处于活动状态, 使用事件, SessionEvents.after_soft_rollback() 检查 Session.is_active 标志。


参数


session– 目标 Session


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_soft_rollbacksession Sessionprevious_transaction: SessionTransaction


在发生任何回滚后执行,包括实际上不在 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(text("select * from some_table"))

参数

方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_transaction_createsession Sessiontransaction SessionTransaction


在创建新的 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


  • 交易


    目标 SessionTransaction


    检测这是否是最外层的 SessionTransaction 与 “subtransaction” 或 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


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_transaction_endsession Sessiontransaction SessionTransaction


SessionTransaction 的 span 结束时执行。


参数形式示例:

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


  • 交易


    目标 SessionTransaction


    检测这是否是最外层的 SessionTransaction 与 “subtransaction” 或 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


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。before_attachsession Sessioninstance _O


在将实例附加到会话之前执行。


参数形式示例:

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


这是在 add、delete 或 merge 导致对象成为 session 的一部分之前调用的。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。before_commitsession Session


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


参数


session– 目标 Session


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。before_flushsessionSession flush_context: UOWTransaction, instances:Sequence[_O]None)


在 flush 进程开始之前执行。


参数形式示例:

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 对象,用于处理 flush 的详细信息。


  • instances– 通常为 None,这是可以传递给 Session.flush() 方法的对象集合(请注意,此用法已弃用)。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。deleted_to_detachedsession Sessioninstance _O


截取特定对象的“已删除到分离”过渡。


参数形式示例:

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() 时,也会为在 flush 中删除的对象调用它 事件,以及对象是否单独 通过 Session.expunge() 从其已删除状态中删除。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。deleted_to_persistentsession Sessioninstance _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() 的在任何其他情况下都不会调用该事件。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。detached_to_persistentsession Sessioninstance _O


截获特定对象的 “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() 调用(如果对象之前不是 与 会话(请注意,标记为 “deleted” 的对象将保持 “persistent” 状态,直到刷新继续)。


注意


如果对象在调用 Session.delete()时,该对象在调用此事件时尚未标记为已删除。要检测已删除的对象,请检查发送到 SessionEvents.persistent_to_detached() to 事件,或者如果需要在 flush 之前拦截已删除的对象,请检查 SessionEvents.before_flush() 事件中的 Session.deleted 集合。


参数

  • session – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


属性 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。dispatch _Dispatch[_ET] = <sqlalchemy.event.base.SessionEventsDispatch 对象>


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。do_orm_executeorm_execute_state ORMExecuteState


拦截代表 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() 的 Session.scalar() 来获取。截至 SQLAlchemy 1.4 中,所有通过 Session.execute() 方法以及相关方法 Session.scalars()、Session.scalar() 等将参与此活动。此事件钩子不适用于 ORM flush 进程内部发出的查询,即 Flushing 中描述的过程。


注意


SessionEvents.do_orm_execute() 事件钩子仅针对 ORM 语句执行触发,即通过 Session.execute()Session 对象上的类似方法调用的语句。它不会触发仅由 SQLAlchemy Core 调用的语句,即使用 Connection.execute() 直接调用的语句,或者以其他方式源自 Engine 对象而不涉及任何 Session 的语句。要拦截所有 SQL 执行,而不管 Core API 还是 ORM API 正在使用中,请参阅 ConnectionEvents 中的事件钩子,例如 ConnectionEvents.before_execute() ConnectionEvents.before_cursor_execute()


此外,此事件钩子不适用于在 ORM flush 进程内部发出的查询,即 Flushing 中描述的过程;要拦截 flush 进程中的步骤,请参阅 Persistence EventsMapper 级别的 Flush 事件中描述的事件钩子。


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


该钩子打算取代 Query._execute_and_instances 可以在 SQLAlchemy 1.4 之前子类化的方法。


参数


orm_execute_stateORMExecuteState 的实例 ,它还包含有关当前执行的所有信息 作为辅助函数,用于派生其他通常所需的 信息。 有关详细信息,请参阅该对象。


另请参阅


执行事件 - 有关如何使用的 SessionEvents.do_orm_execute() 顶级文档


ORMExecuteState - 传递给 SessionEvents.do_orm_execute() event 中包含有关要调用的语句的所有信息。它还提供了一个接口来扩展当前语句、选项和参数,以及一个允许在任何时候以编程方式调用语句的选项。


ORM Query Events - 包括使用 SessionEvents.do_orm_execute()


Dogpile Caching - 如何利用 SessionEvents.do_orm_execute() 事件钩子将 Dogpile 缓存与 ORM Session 集成的示例。


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


在 1.4 版本加入.


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。loaded_as_persistentsession Sessioninstance _O


截获特定对象的 “loaded as persistent” 过渡。


参数形式示例:

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 类或实例,而不是 mapper 或类层次结构,并且可以与其他 session 生命周期事件顺利集成。在调用此事件时,保证该对象存在于会话的标识映射中。


注意


在 Eager 加载器可能已完成之前,在 loader 进程中调用此事件,并且对象的状态可能未完成。此外,对对象调用行级刷新作会将该对象放入新的 loader 上下文中,从而干扰现有的 load 上下文。请参阅 InstanceEvents.load() 上的注释,了解有关使用 SessionEvents.restore_load_context 参数,其中 的工作方式与 InstanceEvents.restore_load_context ,以解决此情况。


参数

  • session – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。pending_to_persistentsession Sessioninstance _O


截获特定对象的 “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 进程中调用,类似于在 SessionEvents.after_flush() 事件中扫描 Session.new 集合。但是,在这种情况下,当调用事件时,对象已移至持久状态。


参数

  • session – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。pending_to_transientsession Sessioninstance _O


截获特定对象的 “pending to transient” 过渡。


参数形式示例:

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 中逐出时,会发生这种不太常见的转换;当 Session.rollback() 方法回滚事务或使用 Session.expunge() 方法时,可能会发生这种情况。


参数

  • session – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。persistent_to_deletedsession Sessioninstance _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) ...


当在 flush 中从数据库中删除持久对象的身份时,将调用此事件,但该对象仍与 Session 关联,直到事务完成。


如果事务回滚,则对象将再次移动 设置为持久状态,并且 SessionEvents.deleted_to_persistent() event 被调用。如果事务已提交,则对象将变为 detached,这将发出 SessionEvents.deleted_to_detached() 事件。


请注意,虽然 Session.delete() 方法是将对象标记为已删除的主要公共接口,但许多对象由于级联规则而被删除,这些规则并不总是在 flush 时间之前确定。因此,在刷新继续之前,无法捕获将要删除的每个对象。因此,该 SessionEvents.persistent_to_deleted() 事件在 flush 结束时调用。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。persistent_to_detachedsession Sessioninstance _O


截获特定对象的 “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 – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


  • deleted —— 布尔值。如果为 True,则表示此对象已移至 detached 状态,因为它已标记为已删除并刷新。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。persistent_to_transientsession Sessioninstance _O


截获特定对象的 “persistent to transient” 过渡。


参数形式示例:

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 中逐出时,会发生这种不太常见的转换;当 Session.rollback() 方法回滚事务时,可能会发生这种情况。


参数

  • session – 目标 Session


  • instance—— 正在作的 ORM 映射实例。


方法 sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。transient_to_pendingsession Sessioninstance _O


截获特定对象的 “transient to pending” 转换。


参数形式示例:

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 事件


Mapper 事件钩子包含与单个或多个 Mapper 对象相关的事件,这些对象是将用户定义的类映射到 Table 对象的中心配置对象。在 Mapper 级别发生的事情类型包括:


对象名称

描述

MapperEvents


定义特定于映射的事件。


sqlalchemy.orm 中。Mapper事件


定义特定于映射的事件。


例如:

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 类本身表示侦听所有 Mapper。


映射器事件提供对映射器关键部分的钩子,包括与对象插桩、对象加载和对象持久性相关的部分。特别是,持久化方法 MapperEvents.before_insert()MapperEvents.before_update() 很受欢迎 用于增强 state 的 PLACES - 但是,这些 方法运行时有几个重要的限制。这 鼓励用户评估 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 - 取消链中的所有后续事件处理程序。


    • other values (其他值) - 由特定侦听器指定的返回值。


类签名


sqlalchemy.orm.MapperEventssqlalchemy.event.Events


方法 sqlalchemy.orm.MapperEvents 中。after_configured


在配置了一系列映射器后调用。


参数形式示例:

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() 通常在首次使用 Mapping 时以及每次提供新的 Mapper 可用并检测到新的 Mapper 使用情况时自动调用。


将此事件与 MapperEvents.mapper_configured() 事件,该事件基于每个映射器调用,而配置 手术收益;与该事件不同,当调用此事件时, 所有交叉配置(例如 backrefs)也将进行 可用于任何待处理的映射器。 此外,与 MapperEvents.before_configured() 相比,在配置一系列映射器之前调用。


此事件只能应用于 Mapper 类,而不能应用于单个映射或映射类。它仅对所有 mapping 作为一个整体调用:

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

方法 sqlalchemy.orm.MapperEvents 中。after_deletemapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 事件,请使用 SessionEvents.do_orm_execute() .


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


在上一步中一次性发出同一类的一批对象的 DELETE 语句后,通常会为这些对象调用该事件。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection¶—— 用于为此实例发出 DELETE 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被删除的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


方法 sqlalchemy.orm.MapperEvents 中。after_insertmapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 事件,请使用 SessionEvents.do_orm_execute() .


此事件用于在 INSERT 发生后修改实例上的仅限 Python 内状态,以及在给定连接上发出其他 SQL 语句。


该事件通常是针对 same class 之后的 INSERT 语句 在上一步中立即发出。在极度 在极少数情况下,这是不可取的, Mapper 对象可以配置为 batch=False,这将导致实例批次被分解为单独的(并且性能更差的)event->persist->事件步骤。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection—— 用于为此实例发出 INSERT 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被持久化的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


方法 sqlalchemy.orm.MapperEvents 中。after_mapper_constructedmapper Mapper[_O]class_: type[_O]


Mapper 完全构建时,接收 class 和 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() 访问 method 和 Mapper.iterate_properties 属性。


此事件与 MapperEvents.before_mapper_configured() 事件,因为它是在 Mapper 的构造函数中调用的,而不是在 registry.configure() 进程中调用的。目前,此事件是唯一适用于希望创建其他映射类以响应此 Mapper 构造的处理程序的事件,当 registry.configure() 下次运行时,该事件将成为同一 configure 步骤的一部分。


2.0.2 新版功能.


另请参阅


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


方法 sqlalchemy.orm.MapperEvents 中。after_updatemapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 的 INSERT、UPDATE 和 DELETE 语句。要拦截 ORM DML 事件,请使用 SessionEvents.do_orm_execute() .


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


对于标记为 “dirty” 的所有实例,甚至那些没有净变化的实例,都会调用此方法 添加到其基于列的属性中,并且没有对其执行任何 UPDATE 语句。当对象的任何基于列的属性调用了“set attribute”作时,或者当其任何集合被修改时,该对象将被标记为脏。如果在更新时,没有基于列的属性有任何净更改,则不会发出 UPDATE 语句。这意味着发送到 MapperEvents.after_update() 的实例是 不保证已发出 UPDATE 语句。


检测对象上基于列的属性是否具有 net 更改,因此会产生 UPDATE 语句,请使用 object_session(instance).is_modified(instance, include_collections=False) .


在上一步中一次性发出同一类的一批对象的 UPDATE 语句后,通常会为该事件调用该事件。在极少数情况下,这是不可取的,可以将 Mapper 配置为batch=False,这将导致实例批次被分解为单独的(并且性能更差的)event->persist->事件步骤。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection– 用于为此实例发出 UPDATE 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被持久化的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


方法 sqlalchemy.orm.MapperEvents 中。before_configured


在配置一系列映射器之前调用。


参数形式示例:

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() 通常在首次使用 Mapping 时以及每次提供新的 Mapper 可用并检测到新的 Mapper 使用情况时自动调用。


此事件只能应用于 Mapper 类,而不能应用于单个映射或映射类。它仅对所有 mapping 作为一个整体调用:

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

方法 sqlalchemy.orm.MapperEvents 中。before_deletemapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 事件,请使用 SessionEvents.do_orm_execute() .


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


在后续步骤中,在立即发出 DELETE 语句之前,通常会为同一类的一批对象调用该事件。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection¶—— 用于为此实例发出 DELETE 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被删除的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


方法 sqlalchemy.orm.MapperEvents 中。before_insertmapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 事件,请使用 SessionEvents.do_orm_execute() .


此事件用于在 INSERT 发生之前修改实例上的本地非对象相关属性,以及在给定连接上发出其他 SQL 语句。


在后续步骤中,在立即发出其 INSERT 语句之前,通常会为同一类的一批对象调用该事件。在极少数情况下,这是不可取的,可以将 Mapper 对象配置为batch=False,这将导致实例批次被分解为单独的(并且性能更差的)event->persist->事件步骤。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection—— 用于为此实例发出 INSERT 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被持久化的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


方法 sqlalchemy.orm.MapperEvents 中。before_mapper_configuredmapper Mapper[_O]class_: type[_O]


在配置特定 mapper 之前调用。


参数形式示例:

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


此事件旨在通过返回接口来允许在 configure 步骤中跳过特定映射器。EXT_SKIP 符号,该符号向 configure_mappers() 调用指示应在当前配置运行中跳过此特定映射器(或使用 propagate=True 的映射器层次结构)。当跳过一个或多个映射器时,“new mappers” 标志将保持设置状态,这意味着在使用映射器时将继续调用 configure_mappers() 函数,以继续尝试配置所有可用的映射器。


与其他 configure 级别的事件相比, MapperEvents.before_configured() MapperEvents.after_configured() MapperEvents.mapper_configured() MapperEvents.before_mapper_configured() event 在使用 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

方法 sqlalchemy.orm.MapperEvents 中。before_updatemapper Mapper[_O]connection 连接target _O


在发出与该实例对应的 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 事件,请使用 SessionEvents.do_orm_execute() .


此事件用于在 UPDATE 发生之前修改实例上的本地非对象相关属性,以及在给定连接上发出其他 SQL 语句。


对于标记为 “dirty” 的所有实例,甚至那些没有净变化的实例,都会调用此方法 添加到其基于列的属性中。当对象的任何基于列的属性调用了“set attribute”作时,或者当其任何集合被修改时,该对象将被标记为脏。如果在更新时,没有基于列的属性有任何净更改,则不会发出 UPDATE 语句。这意味着发送到 MapperEvents.before_update() 的实例是 不能保证会发出 UPDATE 语句,尽管您可以通过修改属性来影响此处的结果,以便确实存在 value 的净变化。


检测对象上基于列的属性是否具有 net changes,因此将生成 UPDATE 语句,请使用 object_session(instance).is_modified(instance, include_collections=False) .


在后续步骤中,在立即发出 UPDATE 语句之前,通常会为同一类的一批对象调用该事件。在极少数情况下,这是不可取的,可以将 Mapper 配置为batch=False,这将导致实例批次被分解为单独的(并且性能更差的)event->persist->事件步骤。


警告


映射器级别的 flush 事件只允许非常有限的作, 仅对正在作的行的本地属性, 以及允许在给定的 连接请完整阅读 Mapper 级别 Flush Events 中的注释,了解有关使用这些方法的指南;通常,SessionEvents.before_flush() method 应该是一般 on-flush 更改的首选。


参数

  • mapper—— 作为此事件目标的 Mapper


  • connection– 用于为此实例发出 UPDATE 语句的 Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。


  • target —— 被持久化的 Map 实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


结果


此事件不支持返回值。


另请参阅


持久性事件


属性 sqlalchemy.orm.MapperEvents 的 Events。dispatch _Dispatch[_ET] = <sqlalchemy.event.base.MapperEventsDispatch 对象>


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向


方法 sqlalchemy.orm.MapperEvents 中。instrument_classmapper Mapper[_O]class_: type[_O]


在首次构造映射器时,在将插桩应用于映射类之前接收类。


参数形式示例:

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 构建的最早阶段。映射器的大多数属性尚未初始化。要在基本状态可用的初始映射器构造中接收事件,例如 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_ —— 映射的类。


方法 sqlalchemy.orm.MapperEvents 中。mapper_configuredmapper Mapper[_O]class_: type[_O]


当特定映射器在 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() 通常在首次使用 Mapping 时以及每次提供新的 Mapper 可用并检测到新的 Mapper 使用情况时自动调用。


调用事件时,映射器应处于其最终状态,但不包括可以从 其他测绘人员;它们可能仍在 configuration作。 双向关系 而是通过 relationship.back_populates 参数 完全可用,因为这种关系样式不依赖于其他可能未配置的 Mapper 来知道它们的存在。


对于保证所有 mapper 都准备就绪的事件,包括仅在其他 mapping上定义的 backrefs,请使用 MapperEvents.after_configured() 事件;此事件仅在所有已知映射都已 完全配置。


MapperEvents.mapper_configured() MapperEvents.before_configured() MapperEvents.after_configured() ,为每个映射器/类单独调用,并将映射器传递给事件本身。对于特定映射器,它也只调用一次。因此,该事件对于受益于在特定 mapper 基础上仅调用一次的配置步骤很有用,这不需要 “backref” 配置必须准备好。


参数

  • mapper—— 作为此事件目标的 Mapper


  • class_ —— 映射的类。


实例事件


实例事件侧重于 ORM 映射实例的构造,包括当它们被实例化为瞬态对象时,当它们从数据库加载并成为持久对象时,以及当对象上发生数据库刷新或过期作时。


对象名称

描述


实例事件


定义特定于对象生命周期的事件。


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。


实例事件与 Mapper 事件密切相关,但更特定于实例及其检测,而不是其持久性系统。


使用 InstanceEvents 时,listen() 函数可以使用多个修饰符。


参数

  • propagate=False– 当为 True 时,事件侦听器应应用于所有继承类以及作为此侦听器目标的类。


  • raw=False– 当 True 时,传递给适用事件侦听器函数的 “target” 参数将是实例的 InstanceState 管理对象,而不是映射的实例本身。


  • restore_load_context=错误


    适用于 InstanceEvents.load()InstanceEvents.refresh() 事件。 在事件 hook 已完成,以便持续的 Eager Load作继续进行 以适当地定位对象。 如果 object 从其中一个 events (如果未设置此标志)。


    在 1.3.14 版本加入.


类签名


sqlalchemy.orm.InstanceEventssqlalchemy.event.Events


属性 sqlalchemy.orm.InstanceEvents. 分派 _Dispatch[_ET] = <sqlalchemy.event.base.InstanceEventsDispatch object>


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向


method sqlalchemy.orm.InstanceEvents. expiretarget _O, attrs:Iterable[str]None) 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。


方法 sqlalchemy.orm.InstanceEvents. first_initmanager ClassManager[_O]cls Type[_O]


在调用特定映射的第一个实例时调用。


参数形式示例:

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. inittarget _Oargs Anykwargs Any


在调用实例的构造函数时接收实例。


参数形式示例:

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__ 方法的位置参数。这是作为 Tuples 传递的,目前是不可变的。


  • kwargs – 传递给 __init__ 方法的关键字参数。此结构可以就地更改。


方法 sqlalchemy.orm.InstanceEvents. init_failuretarget _Oargs Anykwargs Any


在调用实例的构造函数时接收实例,并引发异常。


参数形式示例:

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. loadtarget _Ocontext QueryContext


在 通过 __new__,并且在初始属性填充发生后。


参数形式示例:

from sqlalchemy import event


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

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


这通常发生在根据传入结果行创建实例时,并且在该实例的生命周期内仅调用一次。


警告


在结果行加载期间,当处理为此实例接收的第一行时,将调用此事件。当使用带有面向集合的属性的预先加载时,为了加载后续集合项而要加载/处理的额外行尚未发生。这既可以完全加载集合,也可以确保在此事件处理程序中发生某个作,该作为对象发出另一个数据库加载作,则该对象的“加载上下文”可能会更改并干扰仍在进行中的现有 Eager Loader。


可能导致事件处理程序中的“加载上下文”发生变化的示例包括但不限于:


  • 访问不属于该行的 Deferred 属性将触发 “undefer”作并刷新对象


  • 访问不属于该行的 joined-inheritance 子类上的属性将触发 Refresh作。


从 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” 事件的标志,这将确保在事件钩子完成时恢复对象的加载上下文;如果对象的 Load 上下文发生更改而未设置此标志,则会发出警告。


InstanceEvents.load() 事件也以名为 reconstructor() 的类方法装饰器格式提供。


参数

  • target —— 映射的实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


  • context—— 与当前正在进行的 Query 相对应的 QueryContext。 此参数可能是 如果加载与 Query 不对应,例如在 Session.merge() 期间,则为 None


方法 sqlalchemy.orm.InstanceEvents. pickletarget _Ostate_dict: _InstanceDict None


当其关联的 state 被腌制时接收对象实例。


参数形式示例:

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. refreshtarget _Ocontext QueryContext, attrs:Iterable[str]None 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() 方法进行对比,后者在首次从查询加载对象时调用。


注意


在 Eager 加载器可能已完成之前,在 loader 进程中调用此事件,并且对象的状态可能未完成。此外,对对象调用行级刷新作会将该对象放入新的 loader 上下文中,从而干扰现有的 load 上下文。请参阅 InstanceEvents.load() 上的注释,了解有关使用 InstanceEvents.restore_load_context 参数,以解决此方案。


参数

  • target —— 映射的实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


  • context—— 与当前正在进行的 Query 相对应的 QueryContext


  • attrs—— 填充的属性名称序列,如果填充了所有列映射的非延迟属性,则为 None。


方法 sqlalchemy.orm.InstanceEvents. refresh_flushtarget _Oflush_context UOWTransaction, attrs:Iterable[str]None None


在对象状态持久化期间刷新一个或多个包含列级 default 或 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() 相同,不同之处在于它是在工作单元 flush 进程中调用的,并且仅包含具有列级 default 或 onupdate 处理程序的非主键列,包括 Python 可调用对象以及服务器端默认值和触发器,这些都可以通过 RETURNING 子句获取。


注意


虽然该 InstanceEvents.refresh_flush() 事件是针对已 INSERTed 的对象以及已 UPDATEd 的对象触发的,但该事件主要针对 UPDATE 进程;主要是内部工件,INSERT作也可以触发此事件,请注意,一个 INSERTed 行从此事件中显式省略。 为了 拦截对象的新 INSERTed 状态时, SessionEvents.pending_to_persistent() MapperEvents.after_insert() 是更好的选择。


参数

  • target —— 映射的实例。如果事件配置为 raw=True,则这将是与实例关联的 InstanceState 状态管理对象。


  • flush_context– 内部 UOWTransaction 对象,用于处理 flush 的详细信息。


  • attrs- 填充的属性名称序列。


方法 sqlalchemy.orm.InstanceEvents. unpickletarget _Ostate_dict: _InstanceDict


在解封其关联的 state 后接收对象实例。


参数形式示例:

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__,其中包含被 pickle 的状态字典。


属性事件


当 的单个属性上发生事件时,将触发属性事件 ORM 映射对象。 这些事件构成了以下内容的基础 自定义验证函数以及 backref 处理程序


另请参阅


更改属性行为


对象名称

描述


属性事件


定义对象属性的事件。


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)来停止作。


当将侦听器应用于也具有 Map 子类的 Map 类时,例如使用 Mapper 继承模式时,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” 事件希望接收无条件替换的 “old” 值,即使这需要触发数据库加载。请注意,active_history也可以通过 column_property()relationship()


  • propagate=False– 当为 True 时,不仅会为给定的类属性建立侦听器函数,还会为该类的所有当前子类以及该类的所有未来子类上的同名属性建立侦听器函数,使用侦听插桩事件的附加侦听器。


  • raw=False– 当 True 时,事件的 “target” 参数将是 InstanceState 管理对象,而不是映射的实例本身。


  • retval=False——当 True时,用户定义的事件监听必须从函数返回 “value” 参数。这使侦听函数有机会更改最终用于 “set” 或 “append” 事件的值。


类签名


sqlalchemy.orm.AttributeEvents sqlalchemy.event.Events


method sqlalchemy.orm.AttributeEvents. appendtarget _Ovalue _Tinitiator Event*key EventConstants = EventConstants.NO_KEY→_TNone


接收集合追加事件。


参数形式示例:

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 事件在附加到集合时为每个元素调用。这发生在单项附加以及 “bulk replace”作中。


参数

  • target —— 接收事件的对象实例。如果侦听器是使用 raw=True 注册的,则这将是 InstanceState 对象。


  • value – 被附加的值。如果此侦听器是使用 retval=True 注册的,则侦听器函数必须返回此值或替换它的新值。


  • initiatorEvent 的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播,以及检查信息 关于事件源的信息。


  • 密钥


    使用 AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如 collection[some_key_or_index] = value . 参数未传递 如果 AttributeEvents.include_key 未用于设置事件;这是为了允许 backwards 与不包含 key 参数。


    2.0 版的新Function。


结果


如果事件是使用 retval=True 注册的,则应返回给定值或新的有效值。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。

AttributeEvents.bulk_replace()


方法 sqlalchemy.orm.AttributeEvents. append_wo_mutationtarget _Ovalue _Tinitiator Event*key EventConstants = EventConstants.NO_KEY


接收集合附加事件,其中集合实际上并未发生更改。


参数形式示例:

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() 的不同之处在于,当目标集合中已存在对象时,它会触发用于删除重复的集合(如 sets 和 dictionaries)。该事件没有返回值,并且无法更改给定对象的标识。


该事件用于将对象级联到 Session 中 当集合已经通过 backref 事件发生 mutation 时。


参数

  • target —— 接收事件的对象实例。如果侦听器是使用 raw=True 注册的,则这将是 InstanceState 对象。


  • value —— 如果对象在集合中尚不存在,则将附加的值。


  • initiatorEvent 的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播,以及检查信息 关于事件源的信息。


  • 密钥


    使用 AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如 collection[some_key_or_index] = value . 参数未传递 如果 AttributeEvents.include_key 未用于设置事件;这是为了允许 backwards 与不包含 key 参数。


    2.0 版的新Function。


结果


没有为此事件定义返回值。


在 1.4.15 版本加入.


method sqlalchemy.orm.AttributeEvents. bulk_replacetarget _Ovalues Iterable[_T]initiator Event*, keys:Iterable[EventConstants]None=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 对象之前,可以就地修改该作。这是一个“早期钩子”,在 bulk replace 例程尝试协调集合中已存在的对象以及 net replace作正在删除的对象之前运行。


此方法通常与 AttributeEvents.append() 事件。当同时使用这两个事件时,请注意,批量替换作将为所有新项目调用 AttributeEvents.append() 事件,即使在调用之后 AttributeEvents.bulk_replace() 也是如此 对于整个系列。 为了确定 AttributeEvents.append() 事件是批量替换的一部分,请使用 symbol 属性。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 —— 正在设置的值的序列 (例如列表)。处理程序可以就地修改此列表。


  • initiatorEvent 的实例 表示事件的启动。



  • 使用 AttributeEvents.include_key参数设置为 True,这将是作中使用的键序列 通常仅用于字典更新。 参数未传递 如果 AttributeEvents.include_key 未用于设置事件;这是为了允许 backwards 与不包含 key 参数。


    2.0 版的新Function。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。


属性 sqlalchemy.orm.AttributeEvents. 分派 _Dispatch[_ET] = <sqlalchemy.event.base.AttributeEventsDispatch object>


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向


方法 sqlalchemy.orm.AttributeEvents. dispose_collectiontarget _Ocollection Collection[Any]collection_adapter: CollectionAdapter


接收“collection dispose”事件。


参数形式示例:

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 - 侦听器选项的背景,例如传播到子类。


方法 sqlalchemy.orm.AttributeEvents. init_collectiontarget _Ocollection Type[Collection[Any]], collection_adapter CollectionAdapter


接收 '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


以及在 replace作期间:

u1.addresses = [a2, a3]  #  <- new collection

参数

  • target —— 接收事件的对象实例。如果侦听器是使用 raw=True 注册的,则这将是 InstanceState 对象。


  • collection —— 新集合。 这将始终生成 从指定为 relationship.collection_class,并且将始终为空。


  • collection_adapter—— CollectionAdapter 将调解对集合的内部访问。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。


AttributeEvents.init_scalar() - 此事件的 “标量” 版本。


方法 sqlalchemy.orm.AttributeEvents. init_scalartarget _Ovalue _Tdict_: Dict[Any Any]


接收标量 “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 的行为不同。 这 event 中,可以用来自定义实际返回的值, 假设事件侦听器将镜像 在 Core 上配置的默认生成器 对象。


由于 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 的值。上述代码包括以下功能:


  • 通过在给定dict_中设置值 SOME_CONSTANT,我们指示该值将持久化到数据库中。这将取代 Column 的默认生成器中对 SOME_CONSTANT 的使用。active_column_defaults.py 属性检测中给出的示例说明了对更改的默认值使用相同的方法,例如时间戳生成器。在这个特定示例中,并非绝对必要这样做,因为在任何一种情况下SOME_CONSTANT它都是 INSERT 语句的一部分。


  • 通过建立 retval=True 标志,我们从函数返回的值将由 attribute getter 返回。如果没有这个标志,则假定事件是被动观察者,并且函数的返回值将被忽略。


  • 如果映射的类包含继承的子类,则 propagate=True 标志很重要,该子类也将使用此事件侦听器。如果没有这个标志,继承的子类将不会使用我们的事件处理程序。


在上面的示例中,属性 set 事件 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_ —— 该映射对象的 attribute 字典。这通常是对象的__dict__,但在所有情况下都表示属性系统用于获取此属性的实际值的目标。将值放入此字典中具有值将在工作单元生成的 INSERT 语句中使用的效果。


另请参阅


AttributeEvents.init_collection() - 此事件的集合版本


AttributeEvents - 侦听器选项的背景,例如传播到子类。


属性插桩 - 请参阅 active_column_defaults.py示例。


method sqlalchemy.orm.AttributeEvents. modifiedtarget _Oinitiator Event


接收 'modified' 事件。


参数形式示例:

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() 函数用于触发对属性的 Modify 事件,而 正在设置的任何特定值。


在 1.2 版本加入.


参数

  • target —— 接收事件的对象实例。如果侦听器是使用 raw=True 注册的,则这将是 InstanceState 对象。


  • initiatorEvent 的实例 表示事件的启动。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。


方法 sqlalchemy.orm.AttributeEvents. removetarget _Ovalue _Tinitiator Event*key EventConstants = EventConstants.NO_KEY


接收集合删除事件。


参数形式示例:

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 —— 被删除的值。


  • initiatorEvent 的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播。


  • 密钥


    使用 AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如 del collection[some_key_or_index] 。 参数未传递 如果 AttributeEvents.include_key 未用于设置事件;这是为了允许 backwards 与不包含 key 参数。


    2.0 版的新Function。


结果


没有为此事件定义返回值。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。


method sqlalchemy.orm.AttributeEvents. settarget _Ovalue _Toldvalue _Tinitiator Event


接收标量集事件。


参数形式示例:

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_SETNO_VALUE。如果侦听器注册为 active_history=True,则如果现有值当前已卸载或过期,则将从数据库中加载该属性的上一个值。


  • initiatorEvent 的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播。


结果


如果事件是使用 retval=True 注册的,则应返回给定值或新的有效值。


另请参阅


AttributeEvents - 侦听器选项的背景,例如传播到子类。


查询事件


对象名称

描述


查询事件


Query 的构造中表示事件 对象。


sqlalchemy.orm 中。QueryEvents(查询事件)¶


Query 的构造中表示事件 对象。


旧版功能


QueryEvents 事件方法是旧版 从 SQLAlchemy 2.0 开始,仅适用于直接使用 Query 对象。它们不用于 2.0 样式 语句。对于要拦截和修改 2.0 样式 ORM 的事件,请使用 使用 SessionEvents.do_orm_execute() 钩子。


QueryEvents 钩子现在被 SessionEvents.do_orm_execute() event 钩子。


类签名


sqlalchemy.orm.QueryEventssqlalchemy.event.Events


方法 sqlalchemy.orm.QueryEvents 的 Events。before_compilequery query


接收查询 对象,然后它被组合成 core 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 Query Events 中的新示例,这些示例说明了拦截和修改 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 侦听该事件 parameter set 的查询,以便返回修改后的查询。


如果事件钩子返回新的 Query 对象,则默认情况下 QueryEvents.before_compile() 事件将不允许 “baked” 查询缓存查询。 这直接影响 使用 Baked Query 扩展及其在 Lazy loaders 和 Eager Loaders for relationships. 为了 重新建立正在缓存的查询,应用事件,并在 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 版本加入: - 添加了 “bake_ok” 标志到 QueryEvents.before_compile() 事件,并且不允许通过“baked”扩展进行缓存,如果未设置此标志,则返回新的 Query 对象。


方法 sqlalchemy.orm.QueryEvents 的 Events。before_compile_deletequery query delete_context: BulkDelete


允许在 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() event 被功能更强大的 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 实例;这也是给定的 “delete context” 对象的 .query 属性。


  • delete_context —— 一个 “delete context” 对象,它是 与 中所述的对象类型相同 QueryEvents.after_bulk_delete.delete_context .


在 1.2.17 版本加入.


方法 sqlalchemy.orm.QueryEvents 的 Events。before_compile_updatequery query update_context: BulkUpdate


允许在 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() event 被功能更强大的 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.datetime.now(
                datetime.UTC
            )
    return query


“update context” 对象的 .values 字典也可以就地修改,如上所示。


参数

  • query —— 一个 Query 实例;这也是给定的 “Update Context” 对象的 .query 属性。


  • update_context – 一个 “更新上下文” 对象,它是 与 中所述的对象类型相同 QueryEvents.after_bulk_update.update_context 。该对象在 UPDATE 上下文中具有 .values 属性,该属性是传递给 Query.update() 的参数字典。可以修改此字典以更改生成的 UPDATE 语句的 VALUES 子句。


在 1.2.17 版本加入.


属性 sqlalchemy.orm.QueryEvents。dispatch _Dispatch[_ET] = <sqlalchemy.event.base.QueryEventsDispatch 对象>


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向


Instrumentation 事件


定义 SQLAlchemy 的类检测系统。


这个模块通常对用户应用程序不直接可见,但定义了 ORM 交互性的很大一部分。


instrumentation.py 处理用于状态跟踪的最终用户类的注册。它与 state.py 和 attributes.py 密切交互,分别建立每个实例和每个类属性的插桩。


类插桩系统可以按类或全局自定义,使用 sqlalchemy.ext.instrumentation 模块,它提供了构建和指定 替代检测形式。


对象名称

描述


InstrumentationEvents 检测事件


与类插桩事件相关的事件。


sqlalchemy.orm 中。InstrumentationEvents(插桩事件)¶


与类插桩事件相关的事件。


这里的侦听器支持针对任何新样式类建立,即作为 'type' 的子类的任何对象。然后,将针对该类的事件触发事件。如果将 “propagate=True” 标志传递给 event.listen(),则该事件也将针对该类的子类触发。


Python 类型 builtin 也被接受为目标,使用时具有为所有类发出事件的效果。


请注意,这里的 “propagate” 标志默认为 True,而其他类级事件默认为 False。这意味着当侦听器建立在 superclass 上时,新的 subclasses 也将成为这些事件的主题。


类签名


sqlalchemy.orm.InstrumentationEvents sqlalchemy.event.Events


方法 sqlalchemy.orm.InstrumentationEvents. attribute_instrumentcls ClassManager[_O]key _KTinst _O


在检测属性时调用。


参数形式示例:

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

方法 sqlalchemy.orm.InstrumentationEvents. class_instrumentcls ClassManager[_O]


在检测给定类后调用。


参数形式示例:

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() 中。


方法 sqlalchemy.orm.InstrumentationEvents. class_uninstrumentcls ClassManager[_O]


在给定类未插桩之前调用。


参数形式示例:

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() 中。


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


引用回 _Dispatch 类。


针对 _Dispatch._events 的双向