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 中阅读有关此事件的更多信息。
请务必阅读 跟踪查询、对象和会话更改与事件 章节,了解这些事件的上下文。
对象名称 |
描述 |
|---|---|
|
-
类 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 版本加入.
成员
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(), 调度, 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.SessionEvents(sqlalchemy.event.Events)-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_attach(session: Session, instance: _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_begin(session: Session, transaction: SessionTransaction, connection: 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) ...
参数
transaction¶——SessionTransaction。
connection¶– 将用于 SQL 语句的Connection对象。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_bulk_delete(delete_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- 涉及的Sessionquery-查询对象,此更新作 被召唤。result的CursorResult由于 批量 DELETE作。
在 1.4 版本发生变更: update_context 不再具有QueryContext对象。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_bulk_update(update_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” 对象,其中包含有关更新的详细信息,包括以下属性:session- 涉及的Sessionquery-查询对象,此更新作 被召唤。值传递给Query.update()的result的CursorResult由于 bulk UPDATE作。
在 1.4 版本发生变更: update_context 不再具有QueryContext对象。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_commit(session: 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()事件。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_flush(session: Session, flush_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 开始针对此情况发出警告。
参数
flush_context¶– 内部UOWTransaction对象,用于处理 flush 的详细信息。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_flush_postexec(session: Session, flush_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 是启动自己的事务还是参与更大的事务。
参数
flush_context¶– 内部UOWTransaction对象,用于处理 flush 的详细信息。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_rollback(session: 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标志。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_soft_rollback(session: Session, previous_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"))
参数
previous_transaction¶–SessionTransaction事务性标记对象。 当前的 给定Session的SessionTransaction可通过Session.transaction属性获得。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。after_transaction_create(session: Session, transaction: 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正常运行)。
参数
交易¶ –
检测这是否是最外层的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_end(session: Session, transaction: 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()事件。
参数
交易¶ –
检测这是否是最外层的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_attach(session: Session, instance: _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_commit(session: 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()事件。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。before_flush(session: Session, 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) ...
参数
flush_context¶– 内部UOWTransaction对象,用于处理 flush 的详细信息。
instances¶– 通常为None,这是可以传递给Session.flush()方法的对象集合(请注意,此用法已弃用)。
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。deleted_to_detached(session: Session, instance: _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_persistent(session: Session, instance: _O) None¶
截获特定对象的 “deleted to persistent” 过渡。
参数形式示例:from sqlalchemy import event @event.listens_for(SomeSessionClassOrObject, 'deleted_to_persistent') def receive_deleted_to_persistent(session, instance): "listen for the 'deleted_to_persistent' event" # ... (event handling logic) ...
仅当已删除的对象时,才会发生此转换 由于调用Session.rollback()的在任何其他情况下都不会调用该事件。
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。detached_to_persistent(session: Session, instance: _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集合。
另请参阅
-
属性sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。dispatch: _Dispatch[_ET] = <sqlalchemy.event.base.SessionEventsDispatch 对象>¶
引用回 _Dispatch 类。
针对 _Dispatch._events 的双向
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。do_orm_execute(orm_execute_state: ORMExecuteState) 无¶
拦截代表 ORMSession对象发生的语句执行。
参数形式示例: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 Events 和 Mapper 级别的 Flush 事件中描述的事件钩子。
此事件是一个do_事件,这意味着它能够替换Session.execute()方法通常执行的作。其预期用途包括分片和结果缓存方案,这些方案可能寻求在多个数据库连接中调用同一语句,返回从每个连接合并的结果,或者根本不调用该语句,而是从缓存中返回数据。
该钩子打算取代Query._execute_and_instances可以在 SQLAlchemy 1.4 之前子类化的方法。
参数
orm_execute_state¶ –ORMExecuteState的实例 ,它还包含有关当前执行的所有信息 作为辅助函数,用于派生其他通常所需的 信息。 有关详细信息,请参阅该对象。
另请参阅
执行事件 - 有关如何使用的SessionEvents.do_orm_execute()顶级文档ORMExecuteState- 传递给SessionEvents.do_orm_execute()event 中包含有关要调用的语句的所有信息。它还提供了一个接口来扩展当前语句、选项和参数,以及一个允许在任何时候以编程方式调用语句的选项。
ORM Query Events - 包括使用SessionEvents.do_orm_execute()
Dogpile Caching - 如何利用SessionEvents.do_orm_execute()事件钩子将 Dogpile 缓存与 ORMSession集成的示例。
水平分片 - 水平分片示例 / 扩展依赖于SessionEvents.do_orm_execute()event 钩子在多个后端调用 SQL 语句并返回合并结果。
在 1.4 版本加入.
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。loaded_as_persistent(session: Session, instance: _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,以解决此情况。
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。pending_to_persistent(session: Session, instance: _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集合。但是,在这种情况下,当调用事件时,对象已移至持久状态。
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。pending_to_transient(session: Session, instance: _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()方法时,可能会发生这种情况。
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。persistent_to_deleted(session: Session, instance: _O) None¶
截获特定对象的 “persistent to deleted” 过渡。
参数形式示例:from sqlalchemy import event @event.listens_for(SomeSessionClassOrObject, 'persistent_to_deleted') def receive_persistent_to_deleted(session, instance): "listen for the 'persistent_to_deleted' event" # ... (event handling logic) ...
当在 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_detached(session: Session, instance: _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.expunge()等方法 或Session.close()
调用Session.rollback()方法,当对象是该会话事务的 INSERT 语句的一部分时
参数
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。persistent_to_transient(session: Session, instance: _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()方法回滚事务时,可能会发生这种情况。
另请参阅
-
方法sqlalchemy.orm.SessionEvents 的 SessionEvents 进行访问。transient_to_pending(session: Session, instance: _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()调用。
另请参阅
Mapper 事件¶
Mapper 事件钩子包含与单个或多个 Mapper 对象相关的事件,这些对象是将用户定义的类映射到 Table 对象的中心配置对象。在 Mapper 级别发生的事情类型包括:
基于对象的持久化作 - 最流行的映射器钩子是工作单元钩子,例如MapperEvents.before_insert()、MapperEvents.after_update()等。 这些事件与 更粗粒度的会话级事件,例如SessionEvents.before_flush()的 API 中,它们发生在 flush 进程中,基于每个对象;虽然对对象进行更精细的活动更直接,但Session功能的可用性是有限的。
Mapper 配置事件 - Mapper 钩子的另一类主要类别是 当 Mapper 完成时,当 Mapper 被 Map 时出现的 API 和 映射器集配置为相互引用。 这些事件包括MapperEvents.instrument_class()、MapperEvents.before_mapper_configured()和MapperEvents.mapper_configured()在个人Mapper级别和MapperEvents.before_configured()以及MapperEvents.after_configured()Mapper对象。
对象名称 |
描述 |
|---|---|
|
-
类 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)
可用目标包括:
映射器事件提供对映射器关键部分的钩子,包括与对象插桩、对象加载和对象持久性相关的部分。特别是,持久化方法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 (其他值) - 由特定侦听器指定的返回值。
成员
after_configured(), after_delete(), after_insert(), after_mapper_constructed(), after_update(), before_configured(), before_delete(), before_insert(), before_mapper_configured(), before_update(), 调度, instrument_class(), mapper_configured()
类签名
类sqlalchemy.orm.MapperEvents(sqlalchemy.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_delete(mapper: 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 更改的首选。
参数
connection¶—— 用于为此实例发出 DELETE 语句的Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。
target¶ —— 被删除的 Map 实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。
结果
此事件不支持返回值。
另请参阅
-
方法sqlalchemy.orm.MapperEvents 中。after_insert(mapper: 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 更改的首选。
参数
connection¶—— 用于为此实例发出 INSERT 语句的Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。
target¶ —— 被持久化的 Map 实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。
结果
此事件不支持返回值。
另请参阅
-
方法sqlalchemy.orm.MapperEvents 中。after_mapper_constructed(mapper: 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_update(mapper: 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 更改的首选。
参数
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_delete(mapper: 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 更改的首选。
参数
connection¶—— 用于为此实例发出 DELETE 语句的Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。
target¶ —— 被删除的 Map 实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。
结果
此事件不支持返回值。
另请参阅
-
方法sqlalchemy.orm.MapperEvents 中。before_insert(mapper: 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 更改的首选。
参数
connection¶—— 用于为此实例发出 INSERT 语句的Connection。这为特定于此实例的目标数据库上的当前事务提供了句柄。
target¶ —— 被持久化的 Map 实例。如果事件配置为raw=True,则这将是与实例关联的InstanceState状态管理对象。
结果
此事件不支持返回值。
另请参阅
-
方法sqlalchemy.orm.MapperEvents 中。before_mapper_configured(mapper: 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_update(mapper: 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 更改的首选。
参数
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_class(mapper: 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_): "..."
-
方法sqlalchemy.orm.MapperEvents 中。mapper_configured(mapper: 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” 配置必须准备好。
实例事件¶
实例事件侧重于 ORM 映射实例的构造,包括当它们被实例化为瞬态对象时,当它们从数据库加载并成为持久对象时,以及当对象上发生数据库刷新或过期作时。
对象名称 |
描述 |
|---|---|
|
-
类 sqlalchemy.orm 中。实例事件(InstanceEvents)¶
定义特定于对象生命周期的事件。
例如:from sqlalchemy import event def my_load_listener(target, context): print("on load!") event.listen(SomeClass, "load", my_load_listener)
可用目标包括:
实例事件与 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 版本加入.
成员
dispatch, expire(), first_init(), init(), init_failure(), load(), pickle(), refresh(), refresh_flush(), unpickle()
类签名
类sqlalchemy.orm.InstanceEvents(sqlalchemy.event.Events)-
属性sqlalchemy.orm.InstanceEvents.分派: _Dispatch[_ET] = <sqlalchemy.event.base.InstanceEventsDispatch object>¶
引用回 _Dispatch 类。
针对 _Dispatch._events 的双向
-
methodsqlalchemy.orm.InstanceEvents.expire(target: _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_init(manager: 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()事件之前调用。
-
methodsqlalchemy.orm.InstanceEvents.init(target: _O, args: Any, kwargs: 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_failure(target: _O, args: Any, kwargs: 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__的关键字参数 方法。
-
methodsqlalchemy.orm.InstanceEvents.load(target: _O, context: 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.pickle(target: _O, state_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__,包含要腌制的状态。
-
methodsqlalchemy.orm.InstanceEvents.refresh(target: _O, context: 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_flush(target: _O, flush_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.unpickle(target: _O, state_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” 事件的值。
成员
append()、append_wo_mutation()、bulk_replace()、dispatch、dispose_collection()、init_collection()、init_scalar()、modified()、remove()、set()
类签名
类sqlalchemy.orm.AttributeEvents(sqlalchemy.event.Events)-
methodsqlalchemy.orm.AttributeEvents.append(target: _O, value: _T, initiator: 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注册的,则侦听器函数必须返回此值或替换它的新值。
initiator¶–Event的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播,以及检查信息 关于事件源的信息。
密钥¶ –
使用AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如collection[some_key_or_index] = value. 参数未传递 如果AttributeEvents.include_key未用于设置事件;这是为了允许 backwards 与不包含key参数。
2.0 版的新Function。
结果
如果事件是使用retval=True注册的,则应返回给定值或新的有效值。
-
方法sqlalchemy.orm.AttributeEvents.append_wo_mutation(target: _O, value: _T, initiator: 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¶ —— 如果对象在集合中尚不存在,则将附加的值。
initiator¶–Event的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播,以及检查信息 关于事件源的信息。
密钥¶ –
使用AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如collection[some_key_or_index] = value. 参数未传递 如果AttributeEvents.include_key未用于设置事件;这是为了允许 backwards 与不包含key参数。
2.0 版的新Function。
结果
没有为此事件定义返回值。
在 1.4.15 版本加入.
-
methodsqlalchemy.orm.AttributeEvents.bulk_replace(target: _O, values: 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¶ —— 正在设置的值的序列 (例如列表)。处理程序可以就地修改此列表。
initiator¶–Event的实例 表示事件的启动。
键¶ –
使用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_collection(target: _O, collection: 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_collection(target: _O, collection: 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将调解对集合的内部访问。
-
方法sqlalchemy.orm.AttributeEvents.init_scalar(target: _O, value: _T, dict_: 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示例。
-
methodsqlalchemy.orm.AttributeEvents.modified(target: _O, initiator: 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对象。
initiator¶–Event的实例 表示事件的启动。
另请参阅AttributeEvents- 侦听器选项的背景,例如传播到子类。
-
方法sqlalchemy.orm.AttributeEvents.remove(target: _O, value: _T, initiator: 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¶ —— 被删除的值。
initiator¶–Event的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播。
密钥¶ –
使用AttributeEvents.include_key参数设置为 true,这将是作中使用的键,例如del collection[some_key_or_index]。 参数未传递 如果AttributeEvents.include_key未用于设置事件;这是为了允许 backwards 与不包含key参数。
2.0 版的新Function。
结果
没有为此事件定义返回值。
另请参阅AttributeEvents- 侦听器选项的背景,例如传播到子类。
-
methodsqlalchemy.orm.AttributeEvents.set(target: _O, value: _T, oldvalue: _T, initiator: 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_SET或NO_VALUE。如果侦听器注册为active_history=True,则如果现有值当前已卸载或过期,则将从数据库中加载该属性的上一个值。
initiator¶–Event的实例 表示事件的启动。 可以修改 从 Backref 处理程序的原始值中,以便控制 链式事件传播。
结果
如果事件是使用retval=True注册的,则应返回给定值或新的有效值。
另请参阅AttributeEvents- 侦听器选项的背景,例如传播到子类。
查询事件¶
对象名称 |
描述 |
|---|---|
|
-
类 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.QueryEvents(sqlalchemy.event.Events)-
方法sqlalchemy.orm.QueryEvents 的 Events。before_compile(query: query) 无¶
接收查询对象,然后它被组合成 coreSelect对象。
参数形式示例: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_delete(query: 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
参数
在 1.2.17 版本加入.
-
方法sqlalchemy.orm.QueryEvents 的 Events。before_compile_update(query: 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
模块,它提供了构建和指定
替代检测形式。
对象名称 |
描述 |
|---|---|
|
-
类 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_instrument(cls: ClassManager[_O], key: _KT, inst: _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_instrument(cls: 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_uninstrument(cls: 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 的双向
-