ORM包含多种可供订阅的钩子。
有关最常用的ORM事件的介绍,请参阅部分 使用事件跟踪查询、对象和会话更改 . 事件系统一般在 事件 . 有关连接和低级语句执行的非ORM事件如中所述。 核心事件 .
最基本的事件钩子在ORM级别可用 Session
对象。这里截获的内容包括:
持久性操作 -向数据库发送更改的ORM刷新过程可以使用在刷新的不同部分触发的事件进行扩展,以增加或修改发送到数据库的数据,或者允许在持久性发生时发生其他事情。阅读有关持久性事件的更多信息,请访问 持久性事件 .
对象生命周期事件 -在会话中添加、持久化和删除对象时挂接。更多信息请访问 对象生命周期事件 .
执行事件 -部分 2.0 style 执行模型、针对发出的ORM实体的所有SELECT语句,以及flush进程之外的批量更新和删除语句,都从 Session.execute()
方法使用 SessionEvents.do_orm_execute()
方法。有关此活动的更多信息,请访问 执行事件 .
请务必阅读 使用事件跟踪查询、对象和会话更改 关于这些事件的背景。
Object Name | Description |
---|---|
定义特定于的事件 |
定义特定于的事件 Session
生命周期。
例如。::
from sqlalchemy import event
from sqlalchemy.orm import sessionmaker
def my_before_commit(session):
print("before commit!")
Session = sessionmaker()
event.listen(Session, "before_commit", my_before_commit)
这个 listen()
函数将接受 Session
对象以及的返回结果 sessionmaker()
和 scoped_session()
.
此外,它接受 Session
将侦听器应用于所有 Session
全局实例。
raw=False¶ -- 如果为True,则传递给在单个对象上工作的适用事件侦听器函数的“target”参数将是实例的参数 InstanceState
管理对象,而不是映射实例本身。。版本增加::1.3.14
restore_load_context=False¶ -- 适用于 SessionEvents.loaded_as_persistent()
事件。当事件钩子完成时,恢复对象的加载器上下文,以便正在进行的紧急加载操作继续以适当的对象为目标。如果未设置此标志,则在该事件中将对象移到新的加载程序上下文时发出警告。。版本增加::1.3.14
类签名
class sqlalchemy.orm.SessionEvents
(sqlalchemy.event.Events
)
sqlalchemy.orm.SessionEvents.
after_attach(session, instance)¶在实例连接到会话后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_attach')
def receive_after_attach(session, instance):
"listen for the 'after_attach' event"
# ... (event handling logic) ...
这是在添加、删除或合并之后调用的。
注解
从0.8开始,此事件将触发 之后 该项已与会话完全关联,这与以前的版本不同。对于要求对象尚未成为会话状态的一部分的事件处理程序(例如,在目标对象尚未完成时可能自动刷新的处理程序),请考虑新的 before_attach()
事件。
sqlalchemy.orm.SessionEvents.
after_begin(session, transaction, connection)¶在连接上开始事务后执行
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_begin')
def receive_after_begin(session, transaction, connection):
"listen for the 'after_begin' event"
# ... (event handling logic) ...
transaction¶ -- 这个 SessionTransaction
.
connection¶ -- 这个 Connection
将用于SQL语句的对象。
sqlalchemy.orm.SessionEvents.
after_bulk_delete(delete_context)¶在调用了WHERE表达式的ORM DELETE之后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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(SomeSessionOrFactory, '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 版后已移除: 这个 after_bulk_delete
事件现在接受参数 delete_context
. 对接受上面列出的“已弃用”参数签名的侦听器函数的支持将在将来的版本中删除。
这是由于 Query.delete()
方法。
delete_context¶ -- “删除上下文”对象,其中包含有关更新的详细信息,包括以下属性: * session
- the Session
involved * query
- Query
调用此更新操作的对象。* result
这个 CursorResult
作为批量删除操作的结果返回。
在 1.4 版更改: update_上下文不再具有 QueryContext
与之关联的对象。
sqlalchemy.orm.SessionEvents.
after_bulk_update(update_context)¶在针对WHERE表达式调用ORM更新后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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(SomeSessionOrFactory, '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 版后已移除: 这个 after_bulk_update
事件现在接受参数 update_context
. 对接受上面列出的“已弃用”参数签名的侦听器函数的支持将在将来的版本中删除。
这是由于 Query.update()
方法。
update_context¶ -- “更新上下文”对象,其中包含有关更新的详细信息,包括以下属性: * session
- the Session
involved * query
- Query
调用此更新操作的对象。 * values
The "values" dictionary that was passed to Query.update()
. * result
这个 CursorResult
作为批量更新操作的结果返回。
在 1.4 版更改: update_上下文不再具有 QueryContext
与之关联的对象。
sqlalchemy.orm.SessionEvents.
after_commit(session)¶在提交之后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_commit')
def receive_after_commit(session):
"listen for the 'after_commit' event"
# ... (event handling logic) ...
注解
这个 SessionEvents.after_commit()
钩子是 not 每次冲洗,即 Session
可以在事务范围内多次向数据库发出SQL。要拦截这些事件,请使用 SessionEvents.before_flush()
, SessionEvents.after_flush()
或 SessionEvents.after_flush_postexec()
事件。
注解
这个 Session
不在活动事务中,当 SessionEvents.after_commit()
事件被调用,因此无法发出SQL。要发出与每个事务对应的SQL,请使用 SessionEvents.before_commit()
事件。
sqlalchemy.orm.SessionEvents.
after_flush(session, flush_context)¶在刷新完成后但在调用提交之前执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_flush')
def receive_after_flush(session, flush_context):
"listen for the 'after_flush' event"
# ... (event handling logic) ...
请注意,会话的状态仍然处于预刷新状态,即“新”、“脏”和“已删除”列表仍然显示预刷新状态以及实例属性的历史设置。
警告
此事件在 Session
已发出SQL来修改数据库,但是 之前 它改变了其内部状态以反映这些变化,包括将新插入的对象放置到标识映射中。在此事件中发出的ORM操作(如加载相关项)可能会生成新的标识映射条目,这些条目将立即被替换,有时会导致令人困惑的结果。从版本1.3.9开始,SQLAlchemy将对此情况发出警告。
flush_context¶ -- 内部的 UOWTransaction
处理刷新详细信息的对象。
sqlalchemy.orm.SessionEvents.
after_flush_postexec(session, flush_context)¶在刷新完成后和执行后状态发生后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_flush_postexec')
def receive_after_flush_postexec(session, flush_context):
"listen for the 'after_flush_postexec' event"
# ... (event handling logic) ...
这将在“新”、“脏”和“已删除”列表处于最终状态时进行。实际的commit()可能已经发生,也可能没有发生,这取决于刷新是否启动了自己的事务或是否参与了更大的事务。
flush_context¶ -- 内部的 UOWTransaction
处理刷新详细信息的对象。
sqlalchemy.orm.SessionEvents.
after_rollback(session)¶在实际DBAPI回滚发生后执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_rollback')
def receive_after_rollback(session):
"listen for the 'after_rollback' event"
# ... (event handling logic) ...
请注意,此事件仅在 实际的 对数据库执行回滚-执行回滚 not 每次开火 Session.rollback()
如果基础DBAPI事务已回滚,则调用方法。在许多情况下, Session
在此事件期间不会处于“活动”状态,因为当前事务无效。获得一个 Session
在进行最外层回滚之后,使用 SessionEvents.after_soft_rollback()
事件,检查 Session.is_active
旗帜。
sqlalchemy.orm.SessionEvents.
after_soft_rollback(session, previous_transaction)¶在发生任何回滚之后执行,包括“软”回滚,这些回滚实际上不是在DBAPI级别发出的。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'after_soft_rollback')
def receive_after_soft_rollback(session, previous_transaction):
"listen for the 'after_soft_rollback' event"
# ... (event handling logic) ...
这对应于嵌套回滚和外部回滚,即调用dbapi的rollback()方法的最内部回滚,以及仅从事务堆栈中弹出的封闭回滚调用。
给定的 Session
可用于调用SQL和 Session.query()
通过首先检查 Session.is_active
旗帜:
@event.listens_for(Session, "after_soft_rollback")
def do_something(session, previous_transaction):
if session.is_active:
session.execute("select * from some_table")
previous_transaction¶ -- 这个 SessionTransaction
刚刚关闭的事务标记对象。电流 SessionTransaction
对于给定的 Session
可通过 Session.transaction
属性。
sqlalchemy.orm.SessionEvents.
after_transaction_create(session, transaction)¶当新的 SessionTransaction
创建。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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
)
transaction¶ -- 目标 SessionTransaction
. 检测这是否是最外层 SessionTransaction
与“子事务”或保存点相反,测试 SessionTransaction.parent
属性是 None
::@event.listens_for(session,“after_transaction_create”)def after_transaction_create(session,transaction):if transaction.parent is none:使用顶级事务检测 SessionTransaction
是保存点,请使用 SessionTransaction.nested
属性::@event.listens_for(session,“after_transaction_create”)def after_transaction_create(session,transaction):if transaction.nested:使用保存点事务
sqlalchemy.orm.SessionEvents.
after_transaction_end(session, transaction)¶当 SessionTransaction
末端。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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()
事件。
transaction¶ -- 目标 SessionTransaction
. 检测这是否是最外层 SessionTransaction
与“子事务”或保存点相反,测试 SessionTransaction.parent
属性是 None
::@event.listens_for(session,“after_transaction_create”)def after_transaction_end(session,transaction):if transaction.parent is none:使用顶级事务检测 SessionTransaction
是保存点,请使用 SessionTransaction.nested
属性::@event.listens_for(session,“after_transaction_create”)def after_transaction_end(session,transaction):if transaction.nested:使用保存点事务
sqlalchemy.orm.SessionEvents.
before_attach(session, instance)¶在实例附加到会话之前执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'before_attach')
def receive_before_attach(session, instance):
"listen for the 'before_attach' event"
# ... (event handling logic) ...
这是在添加、删除或合并导致对象成为会话的一部分之前调用的。
sqlalchemy.orm.SessionEvents.
before_commit(session)¶在调用提交之前执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'before_commit')
def receive_before_commit(session):
"listen for the 'before_commit' event"
# ... (event handling logic) ...
注解
这个 SessionEvents.before_commit()
钩子是 not 每次冲洗,即 Session
可以在事务范围内多次向数据库发出SQL。要拦截这些事件,请使用 SessionEvents.before_flush()
, SessionEvents.after_flush()
或 SessionEvents.after_flush_postexec()
事件。
sqlalchemy.orm.SessionEvents.
before_flush(session, flush_context, instances)¶在刷新进程启动之前执行。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'before_flush')
def receive_before_flush(session, flush_context, instances):
"listen for the 'before_flush' event"
# ... (event handling logic) ...
flush_context¶ -- 内部的 UOWTransaction
处理刷新详细信息的对象。
instances¶ -- 通常 None
,这是可以传递给 Session.flush()
方法(请注意,此用法已弃用)。
sqlalchemy.orm.SessionEvents.
deleted_to_detached(session, instance)¶截取特定对象的“删除到分离”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'deleted_to_detached')
def receive_deleted_to_detached(session, instance):
"listen for the 'deleted_to_detached' event"
# ... (event handling logic) ...
当从会话中收回已删除的对象时,将调用此事件。出现这种情况的典型情况是 Session
在其中提交对象已删除;对象从已删除状态移动到分离状态。
当 Session.expunge_all()
或 Session.close()
如果对象通过 Session.expunge()
.
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
deleted_to_persistent(session, instance)¶截取特定对象的“删除到持久”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'deleted_to_persistent')
def receive_deleted_to_persistent(session, instance):
"listen for the 'deleted_to_persistent' event"
# ... (event handling logic) ...
只有当由于调用而还原刷新中成功删除的对象时,才会发生此转换。 Session.rollback()
. 在任何其他情况下都不会调用该事件。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
detached_to_persistent(session, instance)¶拦截特定对象的“分离到持久”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'detached_to_persistent')
def receive_detached_to_persistent(session, instance):
"listen for the 'detached_to_persistent' event"
# ... (event handling logic) ...
此活动是 SessionEvents.after_attach()
仅为此特定转换调用的事件。它通常在 Session.add()
打电话,以及在 Session.delete()
如果对象以前未与 Session
(请注意,标记为“已删除”的对象在刷新进行前仍处于“持久”状态)。
注解
如果对象作为调用的一部分变得持久 Session.delete()
对象是 not 但在调用此事件时标记为已删除。要检测已删除的对象,请检查 deleted
标志发送到 SessionEvents.persistent_to_detached()
在冲洗进行后发生事件,或检查 Session.deleted
在 SessionEvents.before_flush()
事件,如果在刷新之前需要截取已删除的对象。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
do_orm_execute(orm_execute_state)¶根据 Session
.
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'do_orm_execute')
def receive_do_orm_execute(orm_execute_state):
"listen for the 'do_orm_execute' event"
# ... (event handling logic) ...
对于从中调用的所有顶级SQL语句调用此事件 Session.execute()
方法。从SQLAlchemy 1.4开始,所有代表 Session
将流经此方法,因此此事件钩子提供一个点,在调用所有类型的ORM查询之前,可以在该点截获这些查询,并用不同的进程替换它们的执行。
这个活动是 do_
事件,意味着它有能力替换 Session.execute()
方法通常执行。它的预期用途包括分片和结果缓存方案,它们可能寻求跨多个数据库连接调用相同的语句,返回从每个连接中合并的结果,或者根本不调用语句,而是从缓存返回数据。
这个钩子打算用 Query._execute_and_instances
方法,该方法可以在SQLAlchemy 1.4之前子类化。
orm_execute_state¶ -- 一个实例 ORMExecuteState
它包含有关当前执行的所有信息,以及用于派生其他常用信息的助手函数。有关详细信息,请参见该对象。
参见
执行事件 - top level documentation on how
to use SessionEvents.do_orm_execute()
ORMExecuteState
-传递给 SessionEvents.do_orm_execute()
事件,其中包含有关要调用的语句的所有信息。它还提供了一个接口来扩展当前语句、选项和参数,以及一个允许在任何时候以编程方式调用语句的选项。
ORM查询事件 - includes examples of using
SessionEvents.do_orm_execute()
狗堆缓存 -一个如何将Dogpile缓存与ORM集成的示例 Session
利用 SessionEvents.do_orm_execute()
事件挂钩。
水平切分 -水平切分示例/扩展依赖于 SessionEvents.do_orm_execute()
事件钩子在多个后端调用SQL语句并返回合并结果。
1.4 新版功能.
sqlalchemy.orm.SessionEvents.
loaded_as_persistent(session, instance)¶截取特定对象的“作为永久加载”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'loaded_as_persistent')
def receive_loaded_as_persistent(session, instance):
"listen for the 'loaded_as_persistent' event"
# ... (event handling logic) ...
此事件在ORM加载过程中被调用,并且被调用与 InstanceEvents.load()
事件。然而,这里的事件与 Session
类或实例,而不是映射器或类层次结构,并与其他会话生命周期事件顺利集成。当调用此事件时,该对象保证存在于会话的标识映射中。
注解
此事件在加载器进程中调用,在预先加载程序完成之前,并且对象的状态可能未完成。另外,对对象调用行级刷新操作会将对象放入新的加载程序上下文中,从而干扰现有的加载上下文。请参见 InstanceEvents.load()
关于利用 SessionEvents.restore_load_context
参数,其工作方式与 InstanceEvents.restore_load_context
,以解决此问题。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
pending_to_persistent(session, instance)¶截获特定对象的“挂起到永久”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'pending_to_persistent')
def receive_pending_to_persistent(session, instance):
"listen for the 'pending_to_persistent' event"
# ... (event handling logic) ...
此事件在刷新进程中调用,类似于扫描 Session.new
在 SessionEvents.after_flush()
事件。但是,在这种情况下,当调用事件时,对象已经移动到持久状态。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
pending_to_transient(session, instance)¶拦截特定对象的“挂起到暂时”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'pending_to_transient')
def receive_pending_to_transient(session, instance):
"listen for the 'pending_to_transient' event"
# ... (event handling logic) ...
当未刷新的挂起对象从会话中移出时,会发生这种不太常见的转换;当 Session.rollback()
方法回滚事务,或者当 Session.expunge()
方法。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
persistent_to_deleted(session, instance)¶截获特定对象的“持久到已删除”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'persistent_to_deleted')
def receive_persistent_to_deleted(session, instance):
"listen for the 'persistent_to_deleted' event"
# ... (event handling logic) ...
当在刷新过程中从数据库中删除持久对象的标识时,将调用此事件,但该对象仍与 Session
直到事务完成。
如果事务回滚,则对象再次移动到持久状态,并且 SessionEvents.deleted_to_persistent()
调用事件。如果提交事务,则对象将分离,这将发出 SessionEvents.deleted_to_detached()
事件。
注意,当 Session.delete()
方法是将对象标记为已删除的主要公共接口,许多对象由于级联规则而被删除,这些规则在刷新时间之前并不总是确定的。因此,在进行刷新之前,无法捕获将被删除的每个对象。这个 SessionEvents.persistent_to_deleted()
因此,在刷新结束时调用事件。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
persistent_to_detached(session, instance)¶截获特定对象的“持久到分离”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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语句的一部分时
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
persistent_to_transient(session, instance)¶截取特定对象的“持续到暂时”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'persistent_to_transient')
def receive_persistent_to_transient(session, instance):
"listen for the 'persistent_to_transient' event"
# ... (event handling logic) ...
当从会话中移出已刷新的挂起对象时,会发生这种不太常见的转换;当 Session.rollback()
方法回滚事务。
1.1 新版功能.
参见
sqlalchemy.orm.SessionEvents.
transient_to_pending(session, instance)¶截取特定对象的“暂时到挂起”转换。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, '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()
打电话。
1.1 新版功能.
参见
映射器事件钩子包含与单个或多个相关的事件 Mapper
对象,它是将用户定义的类映射到 Table
对象。发生在 Mapper
级别包括:
Per-object persistence operations -最流行的mapper钩子是工作单元钩子,例如 MapperEvents.before_insert()
, MapperEvents.after_update()
这些事件与更粗粒度的会话级事件(如 SessionEvents.before_flush()
因为它们在刷新过程中以每个对象为基础发生;虽然对象上的细粒度活动更简单,但是 Session
功能有限。
映射器配置事件 -映射器钩子的另一个主要类是在映射类、完成映射器时以及在映射器集配置为相互引用时发生的类。这些事件包括 MapperEvents.instrument_class()
, MapperEvents.before_mapper_configured()
和 MapperEvents.mapper_configured()
在个人 Mapper
水平,以及 MapperEvents.before_configured()
和 MapperEvents.after_configured()
在收藏层面 Mapper
物体。
Object Name | Description |
---|---|
定义特定于映射的事件。 |
定义特定于映射的事件。
例如。::
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()
是增强持续状态的流行场所——然而,这些方法在操作时有几个显著的限制。鼓励用户评估 SessionEvents.before_flush()
和 SessionEvents.after_flush()
方法作为更灵活和用户友好的钩子,在刷新期间应用额外的数据库状态。
使用时 MapperEvents
,多个修饰符可用于 listen()
功能。
propagate=False¶ -- 如果为true,则事件侦听器应应用于继承类的所有继承映射器和/或映射器,以及作为此侦听器目标的任何映射器。
raw=False¶ -- 如果为true,则传递给适用事件侦听器函数的“target”参数将是实例的 InstanceState
管理对象,而不是映射实例本身。
retval=False¶ -- 如果为true,则用户定义的事件函数必须具有返回值,其目的是控制后续事件传播,或者通过映射器更改正在进行的操作。可能的返回值为: * sqlalchemy.orm.interfaces.EXT_CONTINUE
- continue event processing normally. * sqlalchemy.orm.interfaces.EXT_STOP
-取消链中的所有后续事件处理程序。*其他值-特定侦听器指定的返回值。
类签名
class 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()
通常在首次使用映射时自动调用,以及每次新映射器可用并检测到新映射器使用时自动调用。
将此事件与 MapperEvents.mapper_configured()
事件,在配置操作进行时按映射器调用;与此事件不同,当调用此事件时,所有交叉配置(例如backrefs)也将对挂起的任何映射器可用。也与 MapperEvents.before_configured()
,在配置映射器系列之前调用。
这个事件可以 only 应用于 Mapper
类或 mapper()
函数,而不是单个映射或映射类。它仅对作为整体的所有映射调用::
from sqlalchemy.orm import mapper
@event.listens_for(mapper, "after_configured")
def go():
# ...
理论上,每个应用程序调用一次此事件,但实际上在新映射器受到 configure_mappers()
打电话。如果在已使用现有映射之后构造新映射,则可能会再次调用此事件。为了确保一个特定的事件只被调用一次,而不再被调用, once=True
可以应用参数(0.9.4中的新参数)::
from sqlalchemy.orm import mapper
@event.listens_for(mapper, "after_configured", once=True)
def go():
# ...
sqlalchemy.orm.MapperEvents.
after_delete(mapper, connection, target)¶在发出与该实例对应的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) ...
此事件用于在给定连接上发出额外的SQL语句,以及执行与删除事件相关的特定于应用程序的簿记。
在上一步中,当同一类的一批对象的DELETE语句同时发出后,通常会调用该事件。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出DELETE语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在删除的映射实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
此事件不支持返回值。
参见
sqlalchemy.orm.MapperEvents.
after_insert(mapper, connection, target)¶在对应于该实例发出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) ...
此事件用于在发生插入后在实例上以仅Python状态进行修改,以及在给定连接上发出其他SQL语句。
在上一步中,一次发出insert语句后,通常会为同一类的一批对象调用该事件。在极为罕见的情况下,这是不可取的, mapper()
可配置为 batch=False
,这将导致成批的实例被分解为单独的(性能更差的)事件->持久化->事件步骤。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出INSERT语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在持久化的映射实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
此事件不支持返回值。
参见
sqlalchemy.orm.MapperEvents.
after_update(mapper, connection, target)¶在发出与该实例对应的更新语句后接收对象实例。
示例参数形式:
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) ...
此事件用于在更新发生后在实例上以仅Python状态进行修改,以及在给定连接上发出其他SQL语句。
对标记为“脏”的所有实例调用此方法, even those which have no net changes to their column-based attributes ,并且没有执行任何更新语句。当对象的任何基于列的属性调用了“set attribute”操作或修改了其任何集合时,该对象被标记为脏对象。如果在更新时,没有基于列的属性有任何净更改,则不会发出更新语句。这意味着一个实例被发送到 MapperEvents.after_update()
是 not 已发布更新声明的保证。
要检测对象上基于列的属性是否有净更改,从而导致update语句,请使用 object_session(instance).is_modified(instance, include_collections=False)
.
在上一步中,一批同一类的对象的update语句一次发出之后,通常会调用该事件。在极为罕见的情况下,这是不可取的, mapper()
可配置为 batch=False
,这将导致成批的实例被分解为单独的(性能更差的)事件->持久化->事件步骤。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出更新语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在持久化的映射实例。如果事件配置为 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()
通常在首次使用映射时自动调用,以及每次新映射器可用并检测到新映射器使用时自动调用。
这个事件可以 only 应用于 Mapper
类或 mapper()
函数,而不是单个映射或映射类。它仅对作为整体的所有映射调用::
from sqlalchemy.orm import mapper
@event.listens_for(mapper, "before_configured")
def go():
# ...
将此事件与 MapperEvents.after_configured()
,在配置了一系列映射器之后调用,以及 MapperEvents.before_mapper_configured()
和 MapperEvents.mapper_configured()
,两者都是在每个映射器的基础上调用的。
理论上,每个应用程序调用一次此事件,但实际上在新映射器受到 configure_mappers()
打电话。如果在已使用现有映射之后构造新映射,则可能会再次调用此事件。为了确保一个特定的事件只被调用一次,而不再被调用, once=True
可以应用参数(0.9.4中的新参数)::
from sqlalchemy.orm import mapper
@event.listens_for(mapper, "before_configured", once=True)
def go():
# ...
0.9.3 新版功能.
sqlalchemy.orm.MapperEvents.
before_delete(mapper, connection, target)¶在对应于该实例发出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) ...
此事件用于在给定连接上发出额外的SQL语句,以及执行与删除事件相关的特定于应用程序的簿记。
在稍后的步骤中,在同时发出delete语句之前,通常会为同一类的一批对象调用该事件。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出DELETE语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在删除的映射实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
此事件不支持返回值。
参见
sqlalchemy.orm.MapperEvents.
before_insert(mapper, connection, target)¶在对应于该实例发出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) ...
此事件用于在发生插入之前修改实例上与本地、非对象相关的属性,以及在给定连接上发出其他SQL语句。
在后面的步骤中,在一次性发出INSERT语句之前,通常会为同一类的一批对象调用事件。在极为罕见的情况下,这是不可取的, mapper()
可配置为 batch=False
,这将导致成批的实例被分解为单独的(性能更差的)事件->持久化->事件步骤。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出INSERT语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在持久化的映射实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
此事件不支持返回值。
参见
sqlalchemy.orm.MapperEvents.
before_mapper_configured(mapper, class_)¶在配置特定映射器之前调用。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'before_mapper_configured')
def receive_before_mapper_configured(mapper, class_):
"listen for the 'before_mapper_configured' event"
# ... (event handling logic) ...
此事件旨在通过返回 interfaces.EXT_SKIP
符号,表示 configure_mappers()
调用这个特定的映射器(或映射器的层次结构,如果 propagate=True
应在当前配置运行中跳过。当跳过一个或多个映射器时,“新映射器”标志将保持设置状态,这意味着 configure_mappers()
使用映射器时将继续调用函数,以继续尝试配置所有可用的映射器。
与其他配置级别事件相比, MapperEvents.before_configured()
, MapperEvents.after_configured()
和 MapperEvents.mapper_configured()
,则:meth;.mapperEvents.Before_mapper_configured`事件在向注册时提供有意义的返回值。 ``retval=True` 参数。
1.3 新版功能.
例如。::
from sqlalchemy.orm import EXT_SKIP
Base = declarative_base()
DontConfigureBase = declarative_base()
@event.listens_for(
DontConfigureBase,
"before_mapper_configured", retval=True, propagate=True)
def dont_configure(mapper, cls):
return EXT_SKIP
sqlalchemy.orm.MapperEvents.
before_update(mapper, connection, target)¶在发出与该实例对应的更新语句之前接收对象实例。
示例参数形式:
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) ...
此事件用于在更新发生之前修改实例上与本地、非对象相关的属性,以及在给定连接上发出其他SQL语句。
对标记为“脏”的所有实例调用此方法, even those which have no net changes to their column-based attributes . 当对象的任何基于列的属性调用了“set attribute”操作或修改了其任何集合时,该对象被标记为脏对象。如果在更新时,没有基于列的属性有任何净更改,则不会发出更新语句。这意味着一个实例被发送到 MapperEvents.before_update()
是 not 保证将发出更新语句,尽管您可以通过修改属性来影响此处的结果,从而使值确实存在净变化。
若要检测对象上基于列的属性是否有净更改,从而生成更新语句,请使用 object_session(instance).is_modified(instance, include_collections=False)
.
在稍后的步骤中,在一次发出更新语句之前,通常会为同一类的一批对象调用事件。在极为罕见的情况下,这是不可取的, mapper()
可配置为 batch=False
,这将导致成批的实例被分解为单独的(性能更差的)事件->持久化->事件步骤。
警告
映射器级别刷新事件仅允许 非常有限的操作 ,并允许在给定的 Connection
. 请详细阅读 笔记在 映射器级别事件 关于使用这些方法的指南;一般来说, SessionEvents.before_flush()
对于一般的刷新更改,应首选方法。
connection¶ -- 这个 Connection
用于为此实例发出更新语句。这为特定于此实例的目标数据库上的当前事务提供了一个句柄。
target¶ -- 正在持久化的映射实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
此事件不支持返回值。
参见
sqlalchemy.orm.MapperEvents.
instrument_class(mapper, class_)¶在将检测应用于映射类之前,在第一次构造映射器时接收类。
示例参数形式:
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
整体类,或作为将要映射的类的基础的任何未映射类(使用 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, class_)¶当特定映射器在 configure_mappers()
打电话。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'mapper_configured')
def receive_mapper_configured(mapper, class_):
"listen for the 'mapper_configured' event"
# ... (event handling logic) ...
这个 MapperEvents.mapper_configured()
当 configure_mappers()
函数通过尚未配置的映射器的当前列表前进。 configure_mappers()
通常在首次使用映射时自动调用,以及每次新映射器可用并检测到新映射器使用时自动调用。
调用事件时,映射器应处于其最终状态,但 不包括反向引用 可以从其他映射器调用;它们可能仍在配置操作中挂起。而不是通过 relationship.back_populates
参数 will 完全可用,因为这种类型的关系不依赖于其他可能未配置的映射器来知道它们的存在。
对于保证有 all 映射器准备就绪,包括仅在其他映射上定义的backrefs,请使用 MapperEvents.after_configured()
事件;只有在完全配置了所有已知映射之后,才会调用此事件。
这个 MapperEvents.mapper_configured()
事件,不像 MapperEvents.before_configured()
或 MapperEvents.after_configured()
分别为每个映射器/类调用,并将映射器传递给事件本身。对于一个特定的映射器,它也恰好被调用一次。因此,对于配置步骤来说,该事件非常有用,因为在特定的映射器基础上只调用一次,而不需要“backref”配置就已经准备好了。
实例事件集中在ORM映射实例的构造上,包括它们被实例化为 transient 对象,当它们从数据库加载并成为 persistent 对象,以及对对象执行数据库刷新或过期操作时。
Object Name | Description |
---|---|
定义特定于对象生命周期的事件。 |
定义特定于对象生命周期的事件。
例如。::
from sqlalchemy import event
def my_load_listener(target, context):
print("on load!")
event.listen(SomeClass, 'load', my_load_listener)
可用目标包括:
实例事件与映射器事件密切相关,但更特定于实例及其工具,而不是其持久性系统。
使用时 InstanceEvents
,多个修饰符可用于 listen()
功能。
propagate=False¶ -- 如果为true,则事件侦听器应应用于所有继承类以及作为此侦听器目标的类。
raw=False¶ -- 如果为true,则传递给适用事件侦听器函数的“target”参数将是实例的 InstanceState
管理对象,而不是映射实例本身。
restore_load_context=False¶ -- 适用于 InstanceEvents.load()
和 InstanceEvents.refresh()
事件。当事件钩子完成时,恢复对象的加载器上下文,以便正在进行的紧急加载操作继续以适当的对象为目标。如果对象从这些事件之一移动到新的加载程序上下文,则发出警告,如果未设置此标志。。版本增加::1.3.14
类签名
class sqlalchemy.orm.InstanceEvents
(sqlalchemy.event.Events
)
sqlalchemy.orm.InstanceEvents.
expire(target, attrs)¶在对象实例的属性或某个子集过期后接收该实例。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'expire')
def receive_expire(target, attrs):
"listen for the 'expire' event"
# ... (event handling logic) ...
“keys”是属性名的列表。如果没有,则整个状态将过期。
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
attrs¶ -- 过期的属性名序列,如果所有属性都过期,则为无。
sqlalchemy.orm.InstanceEvents.
first_init(manager, cls)¶当调用特定映射的第一个实例时调用。
示例参数形式:
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()
调用事件。
sqlalchemy.orm.InstanceEvents.
init(target, args, kwargs)¶调用其构造函数时接收实例。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'init')
def receive_init(target, args, kwargs):
"listen for the 'init' event"
# ... (event handling logic) ...
此方法仅在对象的userland构造期间与对象的构造函数一起调用,例如 __init__
方法。当从数据库加载对象时,不会调用它;请参见 InstanceEvents.load()
事件以拦截数据库加载。
事件在实际 __init__
调用对象的构造函数。这个 kwargs
可以在适当的位置修改字典,以影响传递到的内容 __init__
.
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
args¶ -- 传递给的位置参数 __init__
方法。这是作为元组传递的,当前是不可变的。
kwargs¶ -- 传递给的关键字参数 __init__
方法。这种结构 can 就地更改。
sqlalchemy.orm.InstanceEvents.
init_failure(target, args, kwargs)¶当其构造函数被调用时接收实例,并引发异常。
示例参数形式:
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) ...
此方法仅在对象的userland构造期间与对象的构造函数一起调用,例如 __init__
方法。当从数据库加载对象时,不会调用它。
事件在引发异常后被调用 __init__
方法被捕获。调用事件后,原始异常将被向外重新引发,因此对象的构造仍会引发异常。引发的实际异常和堆栈跟踪应出现在 sys.exc_info()
.
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
args¶ -- 传递给的位置参数 __init__
方法。
kwargs¶ -- 传递给的关键字参数 __init__
方法。
sqlalchemy.orm.InstanceEvents.
load(target, context)¶通过以下方式创建对象实例后接收该实例 __new__
以及在发生初始属性填充之后。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'load')
def receive_load(target, context):
"listen for the 'load' event"
# ... (event handling logic) ...
这通常发生在基于传入结果行创建实例时,并且在该实例的生存期内只调用一次。
警告
在结果行加载期间,在处理为此实例接收的第一行时调用此事件。当对面向集合的属性使用预先加载时,要加载/处理以加载后续集合项的其他行尚未发生。这不仅会导致集合不会被完全加载,而且如果在此事件处理程序中发生某个操作,而该操作为该对象发出另一个数据库加载操作,则该对象的“加载上下文”可能会更改并干扰仍在进行的现有紧急加载程序。
导致事件处理程序中“加载上下文”发生更改的示例包括但不限于:
访问不属于行的延迟属性将触发“取消定义”操作并刷新对象
访问不属于行的联接继承子类上的属性将触发刷新操作。
从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
应用于“加载”事件的标志,这将确保在事件钩子完成时恢复对象的加载上下文;如果对象的加载上下文在未设置此标志的情况下发生更改,则会发出警告。
这个 InstanceEvents.load()
事件也可以用类方法decorator格式调用 reconstructor()
.
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
context¶ -- 这个 QueryContext
对应于电流 Query
正在进行中。这个论点可能是 None
如果负载不符合 Query
,例如在 Session.merge()
.
sqlalchemy.orm.InstanceEvents.
pickle(target, state_dict)¶在对象实例的关联状态被pickle时接收该实例。
示例参数形式:
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__
,包含要腌制的状态。
sqlalchemy.orm.InstanceEvents.
refresh(target, context, attrs)¶从查询刷新一个或多个属性后接收对象实例。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'refresh')
def receive_refresh(target, context, attrs):
"listen for the 'refresh' event"
# ... (event handling logic) ...
把这个和 InstanceEvents.load()
方法,在从查询中首次加载对象时调用。
注解
此事件在加载器进程中调用,在预先加载程序完成之前,并且对象的状态可能未完成。另外,对对象调用行级刷新操作会将对象放入新的加载程序上下文中,从而干扰现有的加载上下文。请参见 InstanceEvents.load()
关于利用 InstanceEvents.restore_load_context
参数,以解决此方案。
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
context¶ -- 这个 QueryContext
对应于电流 Query
正在进行中。
attrs¶ -- 填充的属性名序列,如果填充了所有列映射的非延迟属性,则为无。
sqlalchemy.orm.InstanceEvents.
refresh_flush(target, flush_context, attrs)¶在对象状态持久化期间,在刷新一个或多个包含列级默认或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()
但它是在工作单元刷新过程中调用的,并且只包括具有列级默认或onupdate处理程序的非主键列,包括Python可调用项以及服务器端的默认值和触发器,它们可以通过RETURNING子句获取。
注解
而 InstanceEvents.refresh_flush()
事件对于已插入的对象和已更新的对象都会触发,该事件主要针对更新过程;它主要是一个内部构件,插入操作也可以触发此事件,请注意 插入行的主键列显式省略 从这次事件中。为了截获对象的新插入状态 SessionEvents.pending_to_persistent()
和 MapperEvents.after_insert()
是更好的选择。
1.0.5 新版功能.
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
flush_context¶ -- 内部的 UOWTransaction
处理刷新详细信息的对象。
attrs¶ -- 填充的属性名称序列。
sqlalchemy.orm.InstanceEvents.
unpickle(target, state_dict)¶在取消勾选对象实例的关联状态后接收该实例。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass, 'unpickle')
def receive_unpickle(target, state_dict):
"listen for the 'unpickle' event"
# ... (event handling logic) ...
target¶ -- 映射的实例。如果事件配置为 raw=True
,这将是 InstanceState
与实例关联的状态管理对象。
state_dict¶ -- 词典发送到 __setstate__
,包含已被腌制的状态字典。
属性事件在ORM映射对象的各个属性上发生时触发。这些事件构成了 custom validation functions 以及 backref handlers .
参见
Object Name | Description |
---|---|
定义对象属性的事件。 |
定义对象属性的事件。
这些通常在目标类的类绑定描述符上定义。
例如。::
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()
::
def validate_phone(target, value, oldvalue, initiator):
"Strip non-numeric characters from a phone number"
return re.sub(r'\D', '', value)
# setup listener on UserContact.phone attribute, instructing
# it to use the return value
listen(UserContact.phone, 'set', validate_phone, retval=True)
像上面这样的验证函数也会引发异常,例如 ValueError
停止操作。
这个 AttributeEvents.propagate
当将侦听器应用于也映射了子类的映射类时,标志也很重要,例如使用映射器继承模式时:
@event.listens_for(MySuperClass.attr, 'set', propagate=True)
def receive_set(target, value, initiator):
print("value set: %s" % target)
可用于 listen()
和 listens_for()
功能如下。
active_history=False¶ -- 如果为true,则表示“set”事件希望无条件地接收替换的“old”值,即使这需要触发数据库加载。注意 active_history
也可以通过直接设置 column_property()
和 relationship()
.
propagate=False¶ -- 如果为true,则将不仅为给定的class属性建立listener函数,而且为该类的所有当前子类以及该类的所有未来子类上同名的属性建立listener函数,使用一个额外的侦听器来侦听插入事件。
raw=False¶ -- 如果为true,则事件的“target”参数将是 InstanceState
管理对象,而不是映射实例本身。
retval=False¶ -- 如果为true,则用户定义的事件侦听必须从函数返回“value”参数。这使侦听函数有机会更改最终用于“set”或“append”事件的值。
类签名
class sqlalchemy.orm.AttributeEvents
(sqlalchemy.event.Events
)
sqlalchemy.orm.AttributeEvents.
append(target, value, initiator)¶接收集合追加事件。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass.some_attribute, 'append')
def receive_append(target, value, initiator):
"listen for the 'append' event"
# ... (event handling logic) ...
当附加到集合中时,将为每个元素调用append事件。这发生在单个项目附加和“批量替换”操作中。
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
value¶ -- 附加的值。如果此侦听器注册到 retval=True
,Listener函数必须返回该值,或替换该值的新值。
initiator¶ -- 的实例 Event
表示事件的开始。可以由backref处理程序从其原始值进行修改,以控制链接的事件传播,并检查有关事件源的信息。
如果事件注册在 retval=True
应返回给定值或新的有效值。
sqlalchemy.orm.AttributeEvents.
append_wo_mutation(target, value, initiator)¶接收集合未实际变异的集合追加事件。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass.some_attribute, 'append_wo_mutation')
def receive_append_wo_mutation(target, value, initiator):
"listen for the 'append_wo_mutation' event"
# ... (event handling logic) ...
此事件不同于 AttributeEvents.append()
因为当对象已经存在于目标集合中时,它被触发用于对诸如集合和词典的集合进行去重复。该事件没有返回值,并且无法更改给定对象的标识。
该事件用于将对象级联到 Session
当集合已经通过backref事件发生变异时。
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
value¶ -- 如果集合中尚不存在该对象,将追加的值。
initiator¶ -- 的实例 Event
表示事件的开始。可以由backref处理程序从其原始值进行修改,以控制链接的事件传播,并检查有关事件源的信息。
没有为此事件定义返回值。
1.4.15 新版功能.
sqlalchemy.orm.AttributeEvents.
bulk_replace(target, values, initiator)¶接收集合“大容量替换”事件。
示例参数形式:
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对象之前,可以就地修改这些值。这是一个“早期钩子”,在大容量替换例程尝试协调集合中已经存在的对象以及由net replace操作删除的对象之前运行。
这种方法通常与 AttributeEvents.append()
事件。当使用这两个事件时,请注意大容量替换操作将调用 AttributeEvents.append()
所有新项目的事件,即使在 AttributeEvents.bulk_replace()
已为集合整体调用。为了确定 AttributeEvents.append()
事件是大容量替换的一部分,请使用符号 attributes.OP_BULK_REPLACE
要测试传入的发起程序:
from sqlalchemy.orm.attributes import OP_BULK_REPLACE
@event.listens_for(SomeObject.collection, "bulk_replace")
def process_collection(target, values, initiator):
values[:] = [_make_value(value) for value in values]
@event.listens_for(SomeObject.collection, "append", retval=True)
def process_collection(target, value, initiator):
# make sure bulk_replace didn't already do it
if initiator is None or initiator.op is not OP_BULK_REPLACE:
return _make_value(value)
else:
return value
1.2 新版功能.
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
value¶ -- 正在设置的值的序列(例如列表)。处理程序可以就地修改此列表。
initiator¶ -- 的实例 Event
表示事件的开始。
参见
AttributeEvents
-侦听器选项的背景,如到子类的传播。
sqlalchemy.orm.AttributeEvents.
dispose_collection(target, collection, collection_adapter)¶接收“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()
在释放之前将保持其内容完整;以前,集合将为空。
1.0.0 新版功能: 这个 AttributeEvents.init_collection()
和 AttributeEvents.dispose_collection()
事件。
参见
AttributeEvents
-侦听器选项的背景,如到子类的传播。
sqlalchemy.orm.AttributeEvents.
init_collection(target, collection, collection_adapter)¶接收“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) ...
当首次为空属性生成初始“空集合”时,以及当集合替换为新集合(例如通过集合事件)时,将为基于集合的属性触发此事件。
例如,假设 User.addresses
是基于关系的集合,在此触发事件:
u1 = User()
u1.addresses.append(a1) # <- new collection
以及在更换操作期间:
u1.addresses = [a2, a3] # <- new collection
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
collection¶ -- 新收藏。这将始终由指定为 relationship.collection_class
,并且将始终为空。
collection_adapter¶ -- 这个 CollectionAdapter
它将调解对集合的内部访问。
1.0.0 新版功能: AttributeEvents.init_collection()
和 AttributeEvents.dispose_collection()
事件。
sqlalchemy.orm.AttributeEvents.
init_scalar(target, value, dict_)¶接收标量“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
. 此处的事件可用于自定义实际返回的值,假定事件侦听器将镜像核心上配置的默认生成器。 Column
对象也是如此。
因为默认生成器 Column
可能还会产生一个变化的值,例如时间戳, AttributeEvents.init_scalar()
事件处理程序也可用于 set 新返回的值,以便核心级别的默认生成函数只有效地触发一次,但此时对非持久化对象访问属性。通常,当访问未初始化的属性时,不会对对象的状态进行任何更改(更旧的SQLAlchemy版本实际上更改了对象的状态)。
如果列上的默认生成器返回特定的常量,则可以按如下方式使用处理程序:
SOME_CONSTANT = 3.1415926
class MyClass(Base):
# ...
some_attribute = Column(Numeric, default=SOME_CONSTANT)
@event.listens_for(
MyClass.some_attribute, "init_scalar",
retval=True, propagate=True)
def _init_some_attribute(target, dict_, value):
dict_['some_attribute'] = SOME_CONSTANT
return SOME_CONSTANT
上面,我们初始化属性 MyClass.some_attribute
的价值 SOME_CONSTANT
. 上述代码包括以下功能:
通过设置值 SOME_CONSTANT
在给定的 dict_
,我们指示将此值持久化到数据库。这将取代 SOME_CONSTANT
在默认生成器中 Column
. 这个 active_column_defaults.py
示例如下: 属性检测 说明对更改的默认值(例如时间戳生成器)使用相同的方法。在这个特定的例子中,没有严格必要这样做,因为 SOME_CONSTANT
在这两种情况下都是insert语句的一部分。
通过建立 retval=True
标志,我们从函数返回的值将由属性getter返回。如果没有此标志,则假定事件为被动观察者,并且忽略函数的返回值。
这个 propagate=True
如果映射类包含继承子类,则标志很重要,这也将使用此事件侦听器。如果没有此标志,继承子类将不会使用事件处理程序。
在上面的示例中,属性集事件 AttributeEvents.set()
以及由提供的相关验证功能 validates
是 not 当我们将值应用于给定的 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
下一个侦听器的参数。
1.1 新版功能.
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
value¶ -- 在调用此事件侦听器之前要返回的值。此值以值开头 None
但是,如果存在多个侦听器,则返回上一个事件处理程序函数的值。
dict_¶ -- 此映射对象的属性字典。这通常是 __dict__
对象,但在所有情况下都表示属性系统用于获取此属性的实际值的目标。在本字典中放置该值会影响该值将在工作单元生成的INSERT语句中使用。
参见
AttributeEvents.init_collection()
-此事件的集合版本
AttributeEvents
-侦听器选项的背景,如到子类的传播。
属性检测 -见 active_column_defaults.py
例子。
sqlalchemy.orm.AttributeEvents.
modified(target, initiator)¶接收“已修改”事件。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeClass.some_attribute, 'modified')
def receive_modified(target, initiator):
"listen for the 'modified' event"
# ... (event handling logic) ...
当 flag_modified()
函数用于在不设置任何特定值的情况下触发属性上的修改事件。
1.2 新版功能.
target¶ -- 接收事件的对象实例。如果侦听器注册在 raw=True
,这将是 InstanceState
对象。
initiator¶ -- 的实例 Event
表示事件的开始。
参见
AttributeEvents
-侦听器选项的背景,如到子类的传播。
sqlalchemy.orm.AttributeEvents.
remove(target, value, initiator)¶接收集合移除事件。
示例参数形式:
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处理程序从其原始值进行修改,以控制链接的事件传播。…版本更改::0.9.0 initiator
参数现在作为 Event
对象,并且可以由backref链接事件链中的backref处理程序修改。
没有为此事件定义返回值。
参见
AttributeEvents
-侦听器选项的背景,如到子类的传播。
sqlalchemy.orm.AttributeEvents.
set(target, value, oldvalue, initiator)¶接收标量集事件。
示例参数形式:
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
,Listener函数必须返回该值,或替换该值的新值。
oldvalue¶ -- 正在替换上一个值。这也可能是符号 NEVER_SET
或 NO_VALUE
. 如果侦听器注册在 active_history=True
,如果现有值当前已卸载或过期,则将从数据库加载该属性的上一个值。
initiator¶ -- 的实例 Event
表示事件的开始。可以由backref处理程序从其原始值进行修改,以控制链接的事件传播。…版本更改::0.9.0 initiator
参数现在作为 Event
对象,并且可以由backref链接事件链中的backref处理程序修改。
如果事件注册在 retval=True
应返回给定值或新的有效值。
参见
AttributeEvents
-侦听器选项的背景,如到子类的传播。
Object Name | Description |
---|---|
表示构造中的事件 |
表示构造中的事件 Query
对象。
这个 QueryEvents
钩子现在被 SessionEvents.do_orm_execute()
事件挂钩。
类签名
class sqlalchemy.orm.QueryEvents
(sqlalchemy.event.Events
)
sqlalchemy.orm.QueryEvents.
before_compile(query)¶接收 Query
对象在其组成核心之前 Select
对象。
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeQuery, 'before_compile')
def receive_before_compile(query):
"listen for the 'before_compile' event"
# ... (event handling logic) ...
1.4 版后已移除: 这个 QueryEvents.before_compile()
事件被更有能力的 SessionEvents.do_orm_execute()
钩子。在版本1.4中 QueryEvents.before_compile()
事件是 不再使用 对于ORM级别的属性加载,例如延迟或过期属性以及关系加载器的加载。请参见中的新示例 ORM查询事件 它展示了截取和修改ORM查询的新方法,最常见的目的是添加任意过滤条件。
此事件用于允许更改给定的查询::
@event.listens_for(Query, "before_compile", retval=True)
def no_deleted(query):
for desc in query.column_descriptions:
if desc['type'] is User:
entity = desc['entity']
query = query.filter(entity.deleted == False)
return query
通常应使用 retval=True
参数集,以便可以返回修改后的查询。
这个 QueryEvents.before_compile()
如果事件钩子返回一个新的 Query
对象。这既会影响baked查询扩展的直接使用,也会影响其在lazy loader和eager loader中的操作。为了重新建立正在缓存的查询,应用添加 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 新版功能: -在 QueryEvents.before_compile()
对于返回新的 Query
对象(如果未设置此标志)。
sqlalchemy.orm.QueryEvents.
before_compile_delete(query, delete_context)¶允许修改 Query
内对象 Query.delete()
.
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeQuery, 'before_compile_delete')
def receive_before_compile_delete(query, delete_context):
"listen for the 'before_compile_delete' event"
# ... (event handling logic) ...
1.4 版后已移除: 这个 QueryEvents.before_compile_delete()
事件被更有能力的 SessionEvents.do_orm_execute()
钩子。
像 QueryEvents.before_compile()
事件,此事件应配置为 retval=True
以及修改后的 Query
返回的对象,如:
@event.listens_for(Query, "before_compile_delete", retval=True)
def no_deleted(query, delete_context):
for desc in query.column_descriptions:
if desc['type'] is User:
entity = desc['entity']
query = query.filter(entity.deleted == False)
return query
1.2.17 新版功能.
sqlalchemy.orm.QueryEvents.
before_compile_update(query, update_context)¶允许修改 Query
内对象 Query.update()
.
示例参数形式:
from sqlalchemy import event
@event.listens_for(SomeQuery, 'before_compile_update')
def receive_before_compile_update(query, update_context):
"listen for the 'before_compile_update' event"
# ... (event handling logic) ...
1.4 版后已移除: 这个 QueryEvents.before_compile_update()
事件被更有能力的 SessionEvents.do_orm_execute()
钩子。
像 QueryEvents.before_compile()
事件,如果事件用于更改 Query
对象,它应该配置为 retval=True
以及修改后的 Query
返回的对象,如:
@event.listens_for(Query, "before_compile_update", retval=True)
def no_deleted(query, update_context):
for desc in query.column_descriptions:
if desc['type'] is User:
entity = desc['entity']
query = query.filter(entity.deleted == False)
update_context.values['timestamp'] = datetime.utcnow()
return query
这个 .values
“更新上下文”对象的字典也可以就地修改,如上图所示。
update_context¶ -- “更新上下文”对象,与中描述的对象类型相同。 QueryEvents.after_bulk_update.update_context
.对象具有 .values
更新上下文中的属性,该上下文是传递给的参数字典 Query.update()
. 可以修改这个字典来改变产生的UPDATE语句的VALUES子句。
1.2.17 新版功能.
定义SQLAlchemy的类检测系统。
此模块通常对用户应用程序不直接可见,但它定义了ORM交互活动的很大一部分。
py处理状态跟踪的最终用户类注册。它与state.py和attributes.py紧密交互,分别建立每个实例和每个类的属性检测。
可以使用 sqlalchemy.ext.instrumentation
模块,它提供了构建和指定备用仪表表单的方法。
Object Name | Description |
---|---|
与类检测事件相关的事件。 |
与类检测事件相关的事件。
这里的侦听器支持针对任何新的样式类(即任何属于“type”子类的对象)建立。然后,针对该类的事件将触发事件。如果将“propagate=true”标志传递给event.listen(),那么该类的子类也将触发该事件。
Python type
builtin也被接受为一个目标,当使用时,它具有为所有类发出事件的效果。
注意这里的“传播”标志默认为 True
,与默认为的其他类级事件不同 False
. 这意味着当监听器建立在超类上时,新的子类也将成为这些事件的主题。
类签名
class sqlalchemy.orm.InstrumentationEvents
(sqlalchemy.event.Events
)
sqlalchemy.orm.InstrumentationEvents.
attribute_instrument(cls, key, inst)¶在检测属性时调用。
示例参数形式:
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)¶在检测给定类之后调用。
示例参数形式:
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)¶在给定类未被构造之前调用。
示例参数形式:
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()
.
flambé! the dragon and The Alchemist image designs created and generously donated by Rotem Yaari.
Created using Sphinx 4.2.0.