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

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

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


查询事件

对象名称 描述
QueryEvents 代表在构建Query对象时的事件。
class sqlalchemy.orm.QueryEvents

代表在构建Query对象时的事件。

传统特性

QueryEvents事件方法在 SQLAlchemy 2.0 中已过时,仅适用于直接使用Query对象。它们不适用于 2.0 风格语句。要拦截和修改 2.0 风格 ORM 使用的事件,请使用SessionEvents.do_orm_execute()钩子。

QueryEvents钩子现在已被SessionEvents.do_orm_execute()事件钩子取代。

成员

before_compile(), before_compile_delete(), before_compile_update(), dispatch

类签名

sqlalchemy.orm.QueryEvents (sqlalchemy.event.Events)

method before_compile(query: Query) → None

在核心Select对象之前将Query对象接收到。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeQuery, 'before_compile')
def receive_before_compile(query):
    "listen for the 'before_compile' event"
    # ... (event handling logic) ...

自版本 1.4 起弃用:QueryEvents.before_compile() 事件被更强大的SessionEvents.do_orm_execute() 钩子所取代。在版本 1.4 中,QueryEvents.before_compile() 事件不再用于ORM 级别的属性加载,例如延迟加载或过期属性以及关系加载器的加载。请参阅 ORM 查询事件中的新示例,展示了拦截和修改 ORM 查询的新方法,最常见的目的是添加任意的过滤条件。

此事件旨在允许对查询进行更改:

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

通常应该使用retval=True参数监听事件,以便修改后的查询可以返回。

默认情况下,QueryEvents.before_compile() 事件将禁止“烘焙”查询缓存查询,如果事件钩子返回一个新的Query 对象。这影响了烘焙查询扩展的直接使用以及它在关系的惰性加载器和急切加载器中的操作。为了重新建立被缓存的查询,请应用添加bake_ok标志的事件:

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

bake_ok设置为 True 时,事件钩子只会被调用一次,并且不会为正在被缓存的特定查询的后续调用而调用。

自版本 1.3.11 起新增:- 在QueryEvents.before_compile() 事件中添加了“bake_ok”标志,并且如果未设置此标志,则不允许通过“烘焙”扩展进行缓存的事件处理程序返回一个新的Query 对象。

另请参阅

QueryEvents.before_compile_update()

QueryEvents.before_compile_delete()

使用 before_compile 事件

method before_compile_delete(query: Query, delete_context: BulkDelete) → None

允许对Query 对象进行修改,Query.delete() 内部。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeQuery, 'before_compile_delete')
def receive_before_compile_delete(query, delete_context):
    "listen for the 'before_compile_delete' event"
    # ... (event handling logic) ...

自版本 1.4 弃用:QueryEvents.before_compile_delete()事件已被功能更强大的SessionEvents.do_orm_execute()钩取代。

类似于QueryEvents.before_compile()事件,此事件应配置为retval=True,并返回修改后的Query对象,如下所示

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

参数:

  • query – 一个Query实例;这也是给定“删除上下文”对象的.query属性。
  • delete_context – 一个“删除上下文”对象,与QueryEvents.after_bulk_delete.delete_context中描述的对象类型相同。

新版本 1.2.17 中新增。

另请参阅

QueryEvents.before_compile()

QueryEvents.before_compile_update()

method before_compile_update(query: Query, update_context: BulkUpdate) → None

允许在Query.update()内修改Query对象。

示例参数形式:

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字典也可以像上面示例的那样就地修改。

参数:

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

1.2.17 版中的新内容。

另请参阅

QueryEvents.before_compile()

QueryEvents.before_compile_delete()

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

参考回到 _Dispatch 类。

双向针对 _Dispatch._events

仪器化事件

定义了 SQLAlchemy 的类仪器化系统。

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

instrumentation.py 处理了终端用户类的注册以进行状态跟踪。它与分别建立了每个实例和每个类属性仪器化的 state.py 和 attributes.py 密切交互。

类的仪器化系统可以使用sqlalchemy.ext.instrumentation模块进行每个类或全局基础上的定制化,该模块提供了构建和指定替代仪器化形式的方法。

对象名称 描述
InstrumentationEvents 与类仪器化事件相关的事件。
class sqlalchemy.orm.InstrumentationEvents

与类仪器化事件相关的事件。

这里的监听器支持对任何新风格类进行建立,即任何‘type’的子类对象。然后将为针对该类的事件触发事件。如果传递了“propagate=True”标志给 event.listen(),则该事件也将为该类的子类触发。

Python 的 type 内建函数也被接受为目标,当使用时,将对所有类发出事件。

请注意,此处的“propagate”标志默认为 True,与其他类级别事件不同,后者的默认值为 False。这意味着当在超类上建立侦听器时,新的子类也将成为这些事件的主题。

成员

attribute_instrument(), class_instrument(), class_uninstrument(), dispatch

类签名

sqlalchemy.orm.InstrumentationEvents (sqlalchemy.event.Events)

method attribute_instrument(cls: ClassManager[_O], key: _KT, inst: _O) → None

当属性被仪器化时调用。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeBaseClass, 'attribute_instrument')
def receive_attribute_instrument(cls, key, inst):
    "listen for the 'attribute_instrument' event"
    # ... (event handling logic) ...
method class_instrument(cls: ClassManager[_O]) → None

在给定类被仪器化之后调用。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeBaseClass, 'class_instrument')
def receive_class_instrument(cls):
    "listen for the 'class_instrument' event"
    # ... (event handling logic) ...

要获取ClassManager,请使用manager_of_class()

method class_uninstrument(cls: ClassManager[_O]) → None

在给定类被取消仪器化之前调用。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeBaseClass, 'class_uninstrument')
def receive_class_uninstrument(cls):
    "listen for the 'class_uninstrument' event"
    # ... (event handling logic) ...

要获取ClassManager,请使用manager_of_class()

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

参考 _Dispatch 类。

双向对 _Dispatch._events

会话事件

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

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

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

对象名称 描述
SessionEvents 定义特定于Session生命周期的事件。
class sqlalchemy.orm.SessionEvents

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

例如:

from sqlalchemy import event
from sqlalchemy.orm import sessionmaker
def my_before_commit(session):
    print("before commit!")
Session = sessionmaker()
event.listen(Session, "before_commit", my_before_commit)

listen()函数将接受Session对象,以及sessionmaker()scoped_session()的返回结果。

此外,它接受Session类,将全局应用监听器到所有Session实例。

参数:

  • raw=False
    当为 True 时,传递给适用于单个对象的事件监听器函数的“target”参数将是实例的InstanceState管理对象,而不是映射实例本身。
    新版本 1.3.14 中新增。
  • restore_load_context=False
    适用于SessionEvents.loaded_as_persistent()事件。在事件钩子完成时恢复对象的加载器上下文,以便持续的急切加载操作继续适当地针对对象。如果在此事件中将对象移动到新的加载器上下文而未设置此标志,则会发出警告。
    新版本 1.3.14 中新增。

成员

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

类签名

sqlalchemy.orm.SessionEventssqlalchemy.event.Events

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_attach')
def receive_after_attach(session, instance):
    "listen for the 'after_attach' event"
    # ... (event handling logic) ...

在添加、删除或合并后调用。

注意

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

另请参见

SessionEvents.before_attach()

对象生命周期事件

method after_begin(session: Session, transaction: SessionTransaction, connection: Connection) → None

在连接上启动事务后执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_begin')
def receive_after_begin(session, transaction, connection):
    "listen for the 'after_begin' event"
    # ... (event handling logic) ...

注意

此事件在Session修改其自身内部状态的过程中调用。在此挂钩内调用 SQL 操作,请使用事件提供的Connection;不要直接使用Session运行 SQL 操作。

参数:

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

另请参见

SessionEvents.before_commit()

SessionEvents.after_commit()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

method after_bulk_delete(delete_context: _O) → None

当传统的Query.delete()方法被调用后的事件。

示例参数形式:

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

从版本 0.9 开始更改:SessionEvents.after_bulk_delete()事件现在接受参数SessionEvents.after_bulk_delete.delete_context。将来版本中将删除接受上述“已弃用”的先前参数签名的侦听器函数的支持。

旧特性

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

参数:

delete_context -

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

  • session - 参与的Session

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

  • result - 作为批量删除操作的结果返回的CursorResult

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

另请参阅

QueryEvents.before_compile_delete()

SessionEvents.after_bulk_update()

method after_bulk_update(update_context: _O) → None

用于在调用旧的Query.update()方法之后触发事件。

示例参数形式:

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

从版本 0.9 开始更改:SessionEvents.after_bulk_update()事件现在接受参数SessionEvents.after_bulk_update.update_context。将来版本中将删除接受上述“已弃用”的先前参数签名的侦听器函数的支持。

旧特性

SessionEvents.after_bulk_update() 方法是 SQLAlchemy 2.0 中的一个旧式事件钩子。此事件不参与使用 update() 进行 2.0 风格调用的文档化操作。要使用 2.0 风格,SessionEvents.do_orm_execute() 钩子将拦截这些调用。

参数:

update_context -

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

  • session - 涉及的Session

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

  • values - 传递给Query.update()values字典。

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

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

另请参阅

QueryEvents.before_compile_update()

SessionEvents.after_bulk_delete()

method after_commit(session: Session) → None

在提交之后执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_commit')
def receive_after_commit(session):
    "listen for the 'after_commit' event"
    # ... (event handling logic) ...

SessionEvents.after_commit()钩子不是每次刷新都执行的,也就是说,在事务的范围内,Session 可以多次向数据库发出 SQL。要拦截这些事件,可以使用 SessionEvents.before_flush()SessionEvents.after_flush()SessionEvents.after_flush_postexec() 事件。

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

参数:

session – 目标 Session

请参见

SessionEvents.before_commit()

SessionEvents.after_begin()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

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

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

示例参数形式:

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

注意,会话的状态仍然处于 pre-flush 状态,即’new’、'dirty’和’deleted’列表仍然显示 pre-flush 状态以及实例属性上的历史设置。

警告

此事件在 Session 发出 SQL  修改数据库之后运行,但在它修改内部状态以反映这些更改之前运行,包括将新插入的对象放入标识映射中。在此事件内发出的 ORM  操作(如加载相关项目)可能会产生新的标识映射条目,这些条目将立即被替换,有时会导致混淆的结果。从版本 1.3.9 起,SQLAlchemy  会对此条件发出警告。

参数:

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

请参见

SessionEvents.before_flush()

SessionEvents.after_flush_postexec()

持久性事件

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

在 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 是否启动了自己的事务或者参与了更大的事务。

参数:

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

另请参见

SessionEvents.before_flush()

SessionEvents.after_flush()

持久性事件

method after_rollback(session: Session) → None

在实际发生 DBAPI 回滚后执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_rollback')
def receive_after_rollback(session):
    "listen for the 'after_rollback' event"
    # ... (event handling logic) ...

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

参数:

session – 目标Session

method after_soft_rollback(session: Session, previous_transaction: SessionTransaction) → None

在发生任何回滚后执行,包括“软”回滚,这种回滚在 DBAPI 级别实际上不会发出。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_soft_rollback')
def receive_after_soft_rollback(session, previous_transaction):
    "listen for the 'after_soft_rollback' event"
    # ... (event handling logic) ...

这对应于嵌套和外部回滚,即调用 DBAPI 的 rollback()方法的最内部回滚,以及仅从事务堆栈中弹出自身的封闭回滚调用。

给定的Session可以用于在外部回滚后通过首先检查Session.is_active标志来调用 SQL 和Session.query()操作:

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

参数:

  • session – 目标Session
  • previous_transaction – 刚刚关闭的SessionTransaction事务标记对象。给定Session的当前SessionTransaction可以通过Session.transaction属性获得。
method after_transaction_create(session: Session, transaction: SessionTransaction) → None

当创建新的SessionTransaction时执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_transaction_create')
def receive_after_transaction_create(session, transaction):
    "listen for the 'after_transaction_create' event"
    # ... (event handling logic) ...

此事件与SessionEvents.after_begin()不同,因为它针对每个SessionTransaction总体发生,而不是在个别数据库连接上开始事务时发生。它还用于嵌套事务和子事务,并始终与相应的SessionEvents.after_transaction_end()事件匹配(假设Session正常运行)。

参数:

  • session – 目标Session
  • transaction
    目标SessionTransaction
    要检测此是否为最外层SessionTransaction,而不是“子事务”或 SAVEPOINT,请测试SessionTransaction.parent属性是否为None
@event.listens_for(session, "after_transaction_create")
def after_transaction_create(session, transaction):
    if transaction.parent is None:
        # work with top-level transaction
  • 要检测SessionTransaction是否为 SAVEPOINT,请使用SessionTransaction.nested属性:
@event.listens_for(session, "after_transaction_create")
def after_transaction_create(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction

另请参阅

SessionTransaction

SessionEvents.after_transaction_end()

method after_transaction_end(session: Session, transaction: SessionTransaction) → None

SessionTransaction的跨度结束时执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'after_transaction_end')
def receive_after_transaction_end(session, transaction):
    "listen for the 'after_transaction_end' event"
    # ... (event handling logic) ...

此事件与SessionEvents.after_commit()不同,它对应于所有正在使用的SessionTransaction对象,包括嵌套事务和子事务,并且始终与相应的SessionEvents.after_transaction_create()事件匹配。

参数:

  • session – 目标Session
  • transaction
    目标SessionTransaction
    要检测是否为最外层的SessionTransaction,而不是“子事务”或 SAVEPOINT,请测试SessionTransaction.parent属性是否为None
@event.listens_for(session, "after_transaction_create")
def after_transaction_end(session, transaction):
    if transaction.parent is None:
        # work with top-level transaction
  • 要检测SessionTransaction是否为 SAVEPOINT,请使用SessionTransaction.nested属性:
@event.listens_for(session, "after_transaction_create")
def after_transaction_end(session, transaction):
    if transaction.nested:
        # work with SAVEPOINT transaction

另请参阅

SessionTransaction

SessionEvents.after_transaction_create()

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'before_attach')
def receive_before_attach(session, instance):
    "listen for the 'before_attach' event"
    # ... (event handling logic) ...

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

另请参阅

SessionEvents.after_attach()

对象生命周期事件

method before_commit(session: Session) → None

在调用提交之前执行。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'before_commit')
def receive_before_commit(session):
    "listen for the 'before_commit' event"
    # ... (event handling logic) ...

注意

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

参数:

session – 目标Session

另请参阅

SessionEvents.after_commit()

SessionEvents.after_begin()

SessionEvents.after_transaction_create()

SessionEvents.after_transaction_end()

method before_flush(session: Session, flush_context: UOWTransaction, instances: Sequence[_O] | None) → None

在刷新过程开始之前执。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'before_flush')
def receive_before_flush(session, flush_context, instances):
    "listen for the 'before_flush' event"
    # ... (event handling logic) ...

参数:

  • session – 目标Session
  • flush_context – 处理刷新细节的内部UOWTransaction对象。
  • instances – 通常为None,这是可以传递给Session.flush()方法的对象集合(请注意,此用法已被弃用)。

另请参阅

SessionEvents.after_flush()

SessionEvents.after_flush_postexec()

持久性事件

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

拦截特定对象的“删除到分离”转换。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'deleted_to_detached')
def receive_deleted_to_detached(session, instance):
    "listen for the 'deleted_to_detached' event"
    # ... (event handling logic) ...

当从会话中删除的对象被驱逐时,将调用此事件。典型情况是当删除对象的会话的事务被提交时发生;对象从删除状态移动到分离状态。

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

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'deleted_to_persistent')
def receive_deleted_to_persistent(session, instance):
    "listen for the 'deleted_to_persistent' event"
    # ... (event handling logic) ...

仅当在刷新中成功删除的对象由于调用Session.rollback()而被恢复时,才会发生此转换。在任何其他情况下不会调用该事件。

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'detached_to_persistent')
def receive_detached_to_persistent(session, instance):
    "listen for the 'detached_to_persistent' event"
    # ... (event handling logic) ...

此事件是 SessionEvents.after_attach() 事件的一个特化,仅针对此特定转换调用。它通常在 Session.add() 调用期间调用,以及在对象之前未与 Session 关联的情况下,在 Session.delete() 调用期间调用(请注意,标记为“已删除”的对象在刷新之前仍处于“持久化”状态)。

注意

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

参数:

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

参见

对象生命周期事件

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

参考回到 _Dispatch 类。

双向对抗 _Dispatch._events

method do_orm_execute(orm_execute_state: ORMExecuteState) → 

拦截代表 ORM Session 对象执行的语句。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'do_orm_execute')
def receive_do_orm_execute(orm_execute_state):
    "listen for the 'do_orm_execute' event"
    # ... (event handling logic) ...

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

注意

SessionEvents.do_orm_execute()事件挂钩仅针对 ORM 语句执行触发,即通过Session.execute()和类似方法在Session对象上调用的语句。它会触发仅由 SQLAlchemy Core 调用的语句,即仅通过Connection.execute()直接调用的语句或从不涉及任何SessionEngine对象发出的语句。要拦截所有SQL 执行,无论是否使用 Core 或 ORM API,请参见ConnectionEvents中的事件挂钩,如ConnectionEvents.before_execute()ConnectionEvents.before_cursor_execute()

此事件挂钩不适用于在 ORM 刷新过程内部发出的查询,即在刷新中描述的过程;要拦截刷新过程中的步骤,请参见持久性事件以及映射器级刷新事件中描述的事件挂钩。

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

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

参数:

orm_execute_state - 一个ORMExecuteState的实例,其中包含有关当前执行的所有信息,以及用于推导其他常用信息的辅助函数。有关详细信息,请参阅该对象。

另请参阅

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

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

ORM 查询事件 - 包括使用SessionEvents.do_orm_execute()的示例

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

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

1.4 版本中的新功能。

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

拦截特定对象的“加载为持久性”转换。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'loaded_as_persistent')
def receive_loaded_as_persistent(session, instance):
    "listen for the 'loaded_as_persistent' event"
    # ... (event handling logic) ...

此事件在 ORM 加载过程中被调用,与InstanceEvents.load()事件非常相似。然而,这里的事件可以链接到Session类或实例,而不是映射器或类层次结构,并且与其他会话生命周期事件平滑集成。在调用此事件时,对象保证存在于会话的标识映射中。

注意

此事件在加载器过程中被调用,可能在急加载器完成之前,对象的状态可能不完整。此外,在对象上调用行级刷新操作将使对象进入新的加载器上下文,干扰现有的加载上下文。有关如何使用SessionEvents.restore_load_context参数的背景,请参阅有关使用InstanceEvents.restore_load_context的说明,以解决此场景。

参数:

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

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'pending_to_persistent')
def receive_pending_to_persistent(session, instance):
    "listen for the 'pending_to_persistent' event"
    # ... (event handling logic) ...

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

参数:

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

另请参阅

对象生命周期事件

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

拦截特定对象的“挂起到瞬态”转换。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'pending_to_transient')
def receive_pending_to_transient(session, instance):
    "listen for the 'pending_to_transient' event"
    # ... (event handling logic) ...

当未刷新的挂起对象从会话中驱逐时,会发生这种较少见的转换;这可能发生在Session.rollback()方法回滚事务时,或者在使用Session.expunge()方法时。

参数:

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

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'persistent_to_deleted')
def receive_persistent_to_deleted(session, instance):
    "listen for the 'persistent_to_deleted' event"
    # ... (event handling logic) ...

当持久对象的标识在刷新中从数据库中删除时,将调用此事件,但是对象仍然与Session关联,直到事务完成。

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

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

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'persistent_to_detached')
def receive_persistent_to_detached(session, instance):
    "listen for the 'persistent_to_detached' event"
    # ... (event handling logic) ...

当持久对象从会话中驱逐时,将调用此事件。导致此事件发生的许多条件,包括:

  • 使用Session.expunge()Session.close()等方法
  • 当对象是该会话事务的 INSERT 语句的一部分时,调用Session.rollback()方法

参数:

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

另请参阅

对象生命周期事件

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

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

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'persistent_to_transient')
def receive_persistent_to_transient(session, instance):
    "listen for the 'persistent_to_transient' event"
    # ... (event handling logic) ...

这种较不常见的转换发生在已刷新的挂起对象从会话中被驱逐时;当Session.rollback()方法回滚事务时,这种情况可能发生。

参数:

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

另请参阅

对象生命周期事件

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

拦截特定对象的“瞬态到挂起”转换。

示例参数形式:

from sqlalchemy import event
@event.listens_for(SomeSessionClassOrObject, 'transient_to_pending')
def receive_transient_to_pending(session, instance):
    "listen for the 'transient_to_pending' event"
    # ... (event handling logic) ...

这个事件是SessionEvents.after_attach()事件的一个特例,仅在这个特定的转换中调用。通常在Session.add()调用期间调用。

参数:

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

另请参阅

对象生命周期事件


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

相关文章
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(3)
SqlAlchemy 2.0 中文文档(二十九)
36 4
|
3月前
|
SQL 数据库 Python
SqlAlchemy 2.0 中文文档(二十六)(4)
SqlAlchemy 2.0 中文文档(二十六)
43 2
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(2)
SqlAlchemy 2.0 中文文档(二十九)
34 7
|
3月前
|
SQL 存储 关系型数据库
SqlAlchemy 2.0 中文文档(二十九)(1)
SqlAlchemy 2.0 中文文档(二十九)
41 4
|
3月前
|
SQL 关系型数据库 数据库
SqlAlchemy 2.0 中文文档(二十九)(4)
SqlAlchemy 2.0 中文文档(二十九)
35 4
|
3月前
|
自然语言处理 数据库 Python
SqlAlchemy 2.0 中文文档(二十六)(2)
SqlAlchemy 2.0 中文文档(二十六)
25 2
|
3月前
|
SQL 缓存 数据库连接
SqlAlchemy 2.0 中文文档(二十六)(1)
SqlAlchemy 2.0 中文文档(二十六)
27 2
|
3月前
|
SQL 前端开发 关系型数据库
SqlAlchemy 2.0 中文文档(二十七)(2)
SqlAlchemy 2.0 中文文档(二十七)
28 2
|
3月前
|
SQL 缓存 前端开发
SqlAlchemy 2.0 中文文档(二十七)(5)
SqlAlchemy 2.0 中文文档(二十七)
23 2
|
3月前
|
缓存 自然语言处理 数据库
SqlAlchemy 2.0 中文文档(二十六)(5)
SqlAlchemy 2.0 中文文档(二十六)
29 1