上下文/线程本地会话

优质
小牛编辑
136浏览
2023-12-01

从本节召回 我什么时候做一个 Session ,什么时候提交,什么时候关闭? 介绍了“会话范围”的概念,重点介绍了Web应用程序和链接 Session 一个Web请求。大多数现代Web框架都包含集成工具,因此 Session 可以自动管理,这些工具应该在可用时使用。

sqlAlchemy包含自己的helper对象,这有助于建立用户定义的 Session 范围。第三方集成系统也使用它来帮助构建其集成方案。

该对象是 scoped_session 对象,它表示一个 注册表Session 对象。如果您不熟悉注册表模式,可以在 Patterns of Enterprise Architecture

注解

这个 scoped_session 对象是许多SQLAlChemy应用程序使用的非常流行和有用的对象。但是,重要的是要注意,它呈现的是 只有一种方法 关于……的问题 Session 管理层。如果您是SQLAlChemy的新手,特别是如果您对术语“线程局部变量”感到陌生,我们建议您在可能的情况下首先熟悉现成的集成系统,如 Flask-SQLAlchemyzope.sqlalchemy

A scoped_session 通过调用它,传递它 工厂 可以创建新的 Session 物体。工厂只是在调用时生成新对象的东西,并且在 Session 最常见的工厂是 sessionmaker ,在本节前面介绍。下面我们将说明这种用法:

>>> from sqlalchemy.orm import scoped_session
>>> from sqlalchemy.orm import sessionmaker

>>> session_factory = sessionmaker(bind=some_engine)
>>> Session = scoped_session(session_factory)

这个 scoped_session 我们创建的对象现在将调用 sessionmaker 当我们“调用”注册表时:

>>> some_session = Session()

上面, some_session 是的实例 Session ,我们现在可以使用它与数据库进行对话。同样 Session 也存在于 scoped_session 我们创建的注册表。如果我们第二次去登记处,我们会把 same Session ::

>>> some_other_session = Session()
>>> some_session is some_other_session
True

此模式允许应用程序的不同部分调用全局 scoped_session 以便所有这些区域可以共享同一个会话,而无需显式传递它。这个 Session 我们已经在我们的注册表中建立了,在我们通过调用 scoped_session.remove() ::

>>> Session.remove()

这个 scoped_session.remove() 方法第一次调用 Session.close() 关于电流 Session ,其作用是释放 Session 首先,然后丢弃 Session 本身。”这里的“释放”意味着连接将返回到其连接池,并且任何事务状态都将回滚,最终使用 rollback() 基本DBAPI连接的方法。

在这一点上, scoped_session 对象为“空”,将创建一个 new Session 再次呼叫时。如下图所示,这与 Session 我们以前有过:

>>> new_session = Session()
>>> new_session is some_session
False

上面的一系列步骤简单地说明了“注册表”模式的概念。有了这个基本概念,我们可以讨论这个模式如何进行的一些细节。

隐式方法访问

的工作 scoped_session 很简单;抓住 Session 为所有要求它的人。作为实现更透明访问的一种手段 Session , the scoped_session 还包括 代理行为 也就是说,注册表本身可以像 Session 直接;当在此对象上调用方法时,它们是 代理的 到基础 Session 由登记处维护:

Session = scoped_session(some_factory)

# equivalent to:
#
# session = Session()
# print(session.query(MyClass).all())
#
print(Session.query(MyClass).all())

上述代码完成的任务与获取当前 Session 通过调用注册表,然后使用 Session .

线程本地作用域

熟悉多线程编程的用户会注意到,将任何内容表示为全局变量通常不是一个好主意,因为这意味着全局对象将由多个线程并发访问。这个 Session 对象完全设计为在 non-concurrent 时尚,这在多线程方面的意思是“一次只能在一个线程中”。所以我们上面的例子 scoped_session 用法,其中相同 Session 对象是跨多个调用维护的,这表明某些进程需要到位,以便跨多个线程的多个调用实际上不会获得同一会话的句柄。我们把这个概念叫做 线程本地存储 这意味着使用了一个特殊的对象,该对象将为每个应用程序线程维护一个不同的对象。Python通过 threading.local() 构造。这个 scoped_session 对象默认情况下使用此对象作为存储,因此单个 Session 为所有调用 scoped_session 注册表,但仅在单个线程的作用域内。在不同线程中调用注册表的调用方将获得 Session 实例,该实例位于另一个线程本地。

使用这种技术, scoped_session 提供一种快速且相对简单的(如果熟悉线程本地存储)方法,在应用程序中提供一个可安全从多个线程调用的全局对象。

这个 scoped_session.remove() 方法和往常一样,删除当前 Session 与线程关联(如果有)。然而,一个优势是 threading.local() 对象是,如果应用程序线程本身结束,那么该线程的“存储”也将被垃圾收集。因此,在不需要调用 scoped_session.remove() . 但是,交易本身的范围,即通过 Session.commit()Session.rollback() ,通常仍然是必须在适当的时间显式安排的内容,除非应用程序实际将线程的寿命与事务的寿命绑定在一起。

将线程本地作用域与Web应用程序一起使用

如本节所述 我什么时候做一个 Session ,什么时候提交,什么时候关闭? Web应用程序是围绕 网络请求 以及将此类应用程序与 Session 通常意味着 Session 将与该请求关联。事实证明,大多数python web框架,除了异步框架twisted和tornado等明显的例外,都以一种简单的方式使用线程,以便在单个框架的范围内接收、处理和完成特定的web请求。 工作者线程 . 当请求结束时,工作线程被释放到一个工作线程池中,在该池中可以处理另一个请求。

Web请求和线程的这种简单对应意味着 Session 使用线程意味着它也与在该线程内运行的Web请求关联,反之亦然,前提是 Session 仅在Web请求开始后创建,并在Web请求结束前删除。所以使用 scoped_session 作为一种快速整合 Session 使用Web应用程序。下面的序列图说明了这个流程:

Web Server          Web Framework        SQLAlchemy ORM Code
--------------      --------------       ------------------------------
startup        ->   Web framework        # Session registry is established
                    initializes          Session = scoped_session(sessionmaker())

incoming
web request    ->   web request     ->   # The registry is *optionally*
                    starts               # called upon explicitly to create
                                         # a Session local to the thread and/or request
                                         Session()

                                         # the Session registry can otherwise
                                         # be used at any time, creating the
                                         # request-local Session() if not present,
                                         # or returning the existing one
                                         Session.query(MyClass) # ...

                                         Session.add(some_object) # ...

                                         # if data was modified, commit the
                                         # transaction
                                         Session.commit()

                    web request ends  -> # the registry is instructed to
                                         # remove the Session
                                         Session.remove()

                    sends output      <-
outgoing web    <-
response

利用上述流程,整合 Session 对于Web应用程序,有两个要求:

  1. 创建单个 scoped_session 当Web应用程序首次启动时注册,确保应用程序的其余部分可以访问此对象。

  2. 确保 scoped_session.remove() 当Web请求结束时调用,通常通过与Web框架的事件系统集成来建立“请求结束”事件。

如前所述,上述模式是 只有一种可能的方法 整合一个 Session 在Web框架中,一个特别重要的假设是 Web框架将Web请求与应用程序线程关联 . 然而它是 强烈建议使用Web框架本身提供的集成工具(如果可用) ,而不是 scoped_session .

特别是,虽然使用本地线程比较方便,但是 Session 关联 直接请求 而不是当前线程。关于自定义范围的下一节详细介绍了一个更高级的配置,它可以结合使用 scoped_session 直接基于请求的作用域,或任何类型的作用域。

使用自定义创建的作用域

这个 scoped_session 对象的“线程本地”作用域的默认行为只是关于如何“作用域”的许多选项之一 Session . 自定义范围可以基于任何现有的获取“当前正在使用的对象”的系统来定义。

假设一个Web框架定义了一个库函数 get_current_request() . 使用此框架构建的应用程序可以随时调用此函数,结果将是 Request 表示当前正在处理的请求的对象。如果 Request 对象是可哈希的,那么这个函数可以很容易地与 scoped_sessionSession 请求。下面我们结合Web框架提供的假设事件标记来说明这一点。 on_request_end ,允许在请求结束时调用代码::

from my_web_framework import get_current_request, on_request_end
from sqlalchemy.orm import scoped_session, sessionmaker

Session = scoped_session(sessionmaker(bind=some_engine), scopefunc=get_current_request)

@on_request_end
def remove_session(req):
    Session.remove()

上面,我们举例说明 scoped_session 以通常的方式,除了我们将请求返回函数传递为“scopefunc”。这个指令 scoped_session 每当调用注册表以返回当前 Session . 在这种情况下,特别重要的是,我们要确保实现可靠的“删除”系统,因为本词典不是自行管理的。

上下文会话API

Object NameDescription

scoped_session

提供范围管理 Session 物体。

ScopedRegistry

一种注册表,它可以在“作用域”函数的基础上存储单个类的一个或多个实例。

ThreadLocalRegistry

A ScopedRegistry 使用A threading.local() 用于存储的变量。

class sqlalchemy.orm.scoping.scoped_session(session_factory, scopefunc=None)

提供范围管理 Session 物体。

上下文/线程本地会话 教程。

..警告::

When using :ref:`asyncio_toplevel` the async
version :class:`_asyncio.async_scoped_session` should be
used instead.

类签名

class sqlalchemy.orm.scoping.scoped_session (sqlalchemy.orm.scoping.ScopedSessionMixin)

method sqlalchemy.orm.scoping.scoped_session.__call__(**kw)

inherited from the sqlalchemy.orm.scoping.ScopedSessionMixin.__call__ method of ScopedSessionMixin

返回电流 Session ,使用 scoped_session.session_factory 如果不存在。

参数

**kw -- 关键字参数将传递给 scoped_session.session_factory 可调用,如果存在 Session 不存在。如果 Session 存在并且已传递关键字参数, InvalidRequestError 提高了。

method sqlalchemy.orm.scoping.scoped_session.__init__(session_factory, scopefunc=None)

构建新的 scoped_session .

参数
  • session_factory -- 创建新工厂 Session 实例。这通常是,但不一定是 sessionmaker .

  • scopefunc -- 定义当前作用域的可选函数。如果未通过,则 scoped_session 对象假定“线程本地”范围,并将使用python threading.local() 为了保持电流 Session . 如果传递,函数应返回一个哈希标记;此标记将用作字典中的键,以便存储和检索当前 Session .

method sqlalchemy.orm.scoping.scoped_session.add(instance, _warn=True)

将对象放置在 Session .

代表 Session 代表 scoped_session 班级。

它的状态将在下次刷新操作时保留到数据库中。

重复呼叫 add() 将被忽略。相反的 add()expunge() .

method sqlalchemy.orm.scoping.scoped_session.add_all(instances)

将给定的实例集合添加到此 Session .

代表 Session 代表 scoped_session 班级。

method sqlalchemy.orm.scoping.scoped_session.begin(subtransactions=False, nested=False, _subtrans=False)

在此上开始事务或嵌套事务 Session ,如果还没有开始的话。

代表 Session 代表 scoped_session 班级。

这个 Session 对象特征 自动开始 行为,因此通常不需要调用 Session.begin() 方法。但是,可以使用它来控制事务状态何时开始的范围。

当用于开始最外层的事务时,如果 Session 已在事务内部。

参数
返回

这个 SessionTransaction 对象。注意 SessionTransaction 充当python上下文管理器,允许 Session.begin() 用于“with”块。见 显式开始 举个例子。

参见

自动开始

管理交易

Session.begin_nested()

method sqlalchemy.orm.scoping.scoped_session.begin_nested()

在此会话上开始“嵌套”事务,例如保存点。

代表 Session 代表 scoped_session 班级。

目标数据库和关联的驱动程序必须支持SQL保存点,此方法才能正常运行。

有关保存点事务的文档,请参见 使用保存点 .

返回

这个 SessionTransaction 对象。注意 SessionTransaction 充当上下文管理器,允许 Session.begin_nested() 用于“with”块。见 使用保存点 例如。

参见

使用保存点

可序列化的隔离/保存点/事务性DDL -为使保存点正常工作,SQLite驱动程序需要特殊的解决方法。

method sqlalchemy.orm.scoping.scoped_session.bulk_insert_mappings(mapper, mappings, return_defaults=False, render_nulls=False)

执行给定映射字典列表的大容量插入。

代表 Session 代表 scoped_session 班级。

大容量插入功能允许将普通的python字典用作简单插入操作的源代码,这些插入操作可以更容易地分组到执行效率更高的“executemany”操作中。使用字典时,没有使用“历史记录”或会话状态管理功能,可以减少插入大量简单行时的延迟。

给定的字典中的值通常在不修改核心的情况下传递。 sqlalchemy.sql.expression.Insert() 在对给定映射器映射到的表中的值进行组织之后,构造。

1.0.0 新版功能.

警告

大容量插入功能允许以牺牲大多数其他工作单元功能为代价来降低行的延迟插入。对象管理、关系处理和SQL子句支持等功能包括 悄悄地省略 有利于原始记录的插入。

请注意,SQLAlChemy的较新版本是 大大提高了效率 标准的冲洗过程。它是 强烈推荐 不使用批量方法,因为它们代表SQLAlChemy功能的分支,并且正在慢慢进入遗留状态。新功能,如 使用INSERT、UPDATE和ON CONFLICATION(即upsert)返回ORM对象 都比“批量”方法更有效,并且提供了更可预测的功能。

Please read the list of caveats at ORM兼容性/注意事项 before using this method, and fully test and confirm the functionality of all code developed using these systems.

参数
  • mapper -- 映射类或实际 Mapper 对象,表示映射列表中表示的单个对象。

  • mappings -- 一系列字典,每一个字典都包含要插入的映射行的状态,以映射类上的属性名表示。如果映射引用多个表,例如联接继承映射,则每个字典必须包含要填充到所有表中的所有键。

  • return_defaults -- when True, rows that are missing values which generate defaults, namely integer primary key defaults and sequences, will be inserted one at a time, so that the primary key value is available. In particular this will allow joined-inheritance and other multi-table mappings to insert correctly without the need to provide primary key values ahead of time; however, Session.bulk_insert_mappings.return_defaults greatly reduces the performance gains of the method overall. If the rows to be inserted only refer to a single table, then there is no reason this flag should be set as the returned default information is not used.

  • render_nulls -- 如果为真,则值为 None 将导致insert语句中包含空值,而不是从insert中省略列。这允许插入的所有行具有相同的列集,从而允许将整组行批处理到DBAPI。通常,每个包含与前一行不同的空值组合的列集必须从呈现的insert语句中省略不同系列的列,这意味着它必须作为单独的语句发出。通过传递此标志,可以保证将整组行成批地传递到一个批处理中;但是,成本是忽略列调用的服务器端默认值将被跳过,因此必须小心确保不需要这样做。…警告::设置此标志时, 不会调用服务器端的默认SQL值 对于插入为空的列,将显式发送空值。必须注意确保整个操作不需要调用服务器端默认函数。…添加的版本:1.1

参见

散装作业

Session.bulk_save_objects()

Session.bulk_update_mappings()

method sqlalchemy.orm.scoping.scoped_session.bulk_save_objects(objects, return_defaults=False, update_changed_only=True, preserve_order=True)

对给定的对象列表执行大容量保存。

代表 Session 代表 scoped_session 班级。

批量保存功能允许将映射的对象用作简单插入和更新操作的源,这些操作可以更容易地分组到执行更高的“ExecuteMany”操作中;从对象中提取数据也使用较低的延迟过程来执行,该过程忽略属性是否已被修改。如果是更新,也会忽略SQL表达式。

给定的对象不会添加到会话中,也不会在其上建立其他状态。如果 Session.bulk_save_objects.return_defaults 标志,则服务器生成的主键值将分配给返回的对象,但是 非服务器端默认值 ;这是实施中的一个限制。如果需要有状态对象,请使用标准 Session.add_all() 方法或作为另一种较新的批量插入功能,例如 使用INSERT、UPDATE和ON CONFLICATION(即upsert)返回ORM对象

警告

批量保存功能允许以牺牲大多数其他工作单元功能为代价来降低行的延迟插入/更新。对象管理、关系处理和SQL子句支持等功能包括 悄悄地省略 有利于原始插入/更新记录。

请注意,SQLAlChemy的较新版本是 大大提高了效率 标准的冲洗过程。它是 强烈推荐 不使用批量方法,因为它们代表SQLAlChemy功能的分支,并且正在慢慢进入遗留状态。新功能,如 使用INSERT、UPDATE和ON CONFLICATION(即upsert)返回ORM对象 都比“批量”方法更有效,并且提供了更可预测的功能。

Please read the list of caveats at ORM兼容性/注意事项 before using this method, and fully test and confirm the functionality of all code developed using these systems.

参数
  • objects -- 映射对象实例的序列。当对象被持久化时 notSession 之后。对于每个对象,对象是以插入方式发送还是以更新方式发送取决于 Session 在传统操作中;如果对象具有 InstanceState.key 属性集,则假定对象是“分离的”,并将导致更新。否则,将使用插入。在更新的情况下,语句根据属性的变化进行分组,从而成为每个set子句的主题。如果 update_changed_only 如果为false,则每个对象中存在的所有属性都将应用于update语句,这有助于将这些语句组合到一个更大的executeMany()中,并且还将减少检查属性历史记录的开销。

  • return_defaults -- when True, rows that are missing values which generate defaults, namely integer primary key defaults and sequences, will be inserted one at a time, so that the primary key value is available. In particular this will allow joined-inheritance and other multi-table mappings to insert correctly without the need to provide primary key values ahead of time; however, Session.bulk_save_objects.return_defaults greatly reduces the performance gains of the method overall. It is strongly advised to please use the standard Session.add_all() approach.

  • update_changed_only -- 如果为true,则将根据记录了更改的每个状态中的这些属性呈现update语句。如果为false,则所有存在的属性都将呈现到set子句中,主键属性除外。

  • preserve_order -- 如果为true,则插入和更新的顺序与给定对象的顺序完全匹配。如果为false,则将常见类型的对象分组为插入和更新,以允许更多的批处理机会。…添加的版本:1.3

参见

散装作业

Session.bulk_insert_mappings()

Session.bulk_update_mappings()

method sqlalchemy.orm.scoping.scoped_session.bulk_update_mappings(mapper, mappings)

对给定的映射字典列表执行批量更新。

代表 Session 代表 scoped_session 班级。

批量更新功能允许将普通的python字典用作简单更新操作的源代码,这些更新操作可以更容易地组合到更高性能的“executemany”操作中。使用字典时,没有使用“历史记录”或会话状态管理功能,从而减少了更新大量简单行时的延迟。

1.0.0 新版功能.

警告

批量更新功能允许以牺牲大多数其他工作单元功能为代价来降低行的延迟更新。对象管理、关系处理和SQL子句支持等功能包括 悄悄地省略 有利于记录的原始更新。

请注意,SQLAlChemy的较新版本是 大大提高了效率 标准的冲洗过程。它是 强烈推荐 不使用批量方法,因为它们代表SQLAlChemy功能的分支,并且正在慢慢进入遗留状态。新功能,如 使用INSERT、UPDATE和ON CONFLICATION(即upsert)返回ORM对象 都比“批量”方法更有效,并且提供了更可预测的功能。

Please read the list of caveats at ORM兼容性/注意事项 before using this method, and fully test and confirm the functionality of all code developed using these systems.

参数
  • mapper -- 映射类或实际 Mapper 对象,表示映射列表中表示的单个对象。

  • mappings -- 一系列字典,每一个字典都包含要更新的映射行的状态,根据映射类上的属性名。如果映射引用多个表,例如联接继承映射,则每个字典可能包含与所有表对应的键。所有存在且不属于主键的键都应用于UPDATE语句的SET子句;主键值(必需的)应用于WHERE子句。

参见

散装作业

Session.bulk_insert_mappings()

Session.bulk_save_objects()

method sqlalchemy.orm.scoping.scoped_session.close()

关闭此对象使用的事务性资源和ORM对象 Session

代表 Session 代表 scoped_session 班级。

这将删除与此关联的所有ORM对象 Session ,结束正在进行的任何事务,并 releases 任何 Connection 此对象 Session 本身已从关联的 Engine 对象。然后,该操作将 Session 处于可以再次使用的状态。

小技巧

这个 Session.close() 方法 不会阻止再次使用该会话 。这个 Session 本身实际上并不具有明显的“关闭”状态;它只是表示 Session 将释放所有数据库连接和ORM对象。

在 1.4 版更改: 这个 Session.close() 方法不会立即创建新的 SessionTransaction 对象;相反,新的 SessionTransaction 只有在 Session 再次用于数据库操作。

参见

关闭 - detail on the semantics of Session.close()

method sqlalchemy.orm.scoping.scoped_session.classmethod close_all()

关闭 all 内存中的会话。

代表 Session 代表 scoped_session 班级。

1.3 版后已移除: 这个 Session.close_all() 方法已弃用,将在将来的版本中删除。请参考 close_all_sessions() .

method sqlalchemy.orm.scoping.scoped_session.commit()

刷新挂起的更改并提交当前事务。

代表 Session 代表 scoped_session 班级。

如果没有正在进行的事务,该方法将首先“自动注册”一个新事务并提交。

如果 1.x-style 使用已生效,当前有个保存点正在通过 Session.begin_nested() ,该操作将释放当前保存点,但不提交最外层的数据库事务。

如果 2.0-style 使用通过 Session.future 标志,则最外层的数据库事务无条件提交,自动释放任何有效的保存点。

当使用旧的“自动提交”模式时,此方法只有在事务实际正在进行时才有效,否则将引发错误。类似地,当使用遗留的“subtransactions”时,如果事务正在进行,则该方法将关闭当前的“subtransaction”,而不是实际的数据库事务。

参见

提交

管理交易

method sqlalchemy.orm.scoping.scoped_session.configure(**kwargs)

inherited from the ScopedSessionMixin.configure() method of ScopedSessionMixin

重新配置 sessionmaker 用于此 scoped_session .

sessionmaker.configure() .

method sqlalchemy.orm.scoping.scoped_session.connection(bind_arguments=None, close_with_result=False, execution_options=None, **kw)

返回A Connection 与此对应的对象 Session 对象的事务状态。

代表 Session 代表 scoped_session 班级。

如果这样 Session 配置为 autocommit=False ,要么 Connection 返回与当前事务对应的事务,或者如果没有正在进行的事务,则开始新的事务,并且 Connection 返回(请注意,在发出第一条SQL语句之前,不会使用DBAPI建立事务状态)。

或者,如果 Session 配置为 autocommit=True 一个自组织的 Connection 返回时使用 Engine.connect() 在底层 Engine .

多绑定或未绑定中的模糊性 Session 对象可以通过任何可选关键字参数来解析。这最终使得 get_bind() 解决方法。

参数
  • bind_arguments -- 绑定参数字典。可能包括“mapper”、“bind”、“clause”以及传递给的其他自定义参数 Session.get_bind() .

  • bind -- 已弃用;请使用bindu参数

  • mapper -- 已弃用;请使用bindu参数

  • clause -- 已弃用;请使用bindu参数

  • close_with_result -- 已传递给 Engine.connect() ,表示 Connection 应视为“单机使用”,在关闭第一个结果集时自动关闭。此标志仅在以下情况下才有效 Session 配置了 autocommit=True 并且还没有正在进行的事务。。。已弃用::1.4此参数已弃用,将在SQLAlChemy 2.0中删除

  • execution_options -- 将传递给的执行选项字典 Connection.execution_options()仅在首次采购连接时 . 如果连接已经存在于 Session ,将发出警告并忽略参数。。另请参见: 设置事务隔离级别/DBAPI AUTOCOMMIT

  • **kw -- 已弃用;请使用bindu参数

method sqlalchemy.orm.scoping.scoped_session.delete(instance)

将实例标记为已删除。

代表 Session 代表 scoped_session 班级。

数据库删除操作发生在 flush() .

attribute sqlalchemy.orm.scoping.scoped_session.deleted

此中标记为“已删除”的所有实例的集合 Session

代表 Session 代表 scoped_session 班级。

attribute sqlalchemy.orm.scoping.scoped_session.dirty

所有持久实例的集合被认为是脏的。

代表 Session 代表 scoped_session 班级。

例如。::

some_mapped_object in session.dirty

实例在被修改但未被删除时被视为脏实例。

请注意,此“脏”计算是“乐观的”;大多数属性设置或集合修改操作都会将实例标记为“脏”并将其放置在此集合中,即使属性值没有净更改。在刷新时,将每个属性的值与以前保存的值进行比较,如果没有净更改,则不会发生SQL操作(这是一个更昂贵的操作,因此只在刷新时进行)。

要检查实例是否对其属性进行了可操作的网络更改,请使用 Session.is_modified() 方法。

method sqlalchemy.orm.scoping.scoped_session.execute(statement, params=None, execution_options={}, bind_arguments=None, _parent_execute_state=None, _add_event=None, **kw)

执行SQL表达式构造。

代表 Session 代表 scoped_session 班级。

返回A Result 表示语句执行结果的。

例如。::

from sqlalchemy import select
result = session.execute(
    select(User).where(User.id == 5)
)

API合同 Session.execute() 类似于 Connection.execute() , the 2.0 style 版本 Connection .

在 1.4 版更改: 这个 Session.execute() 方法现在是使用 2.0 style ORM用法。

参数
  • statement -- 可执行语句(即 Executable 表达式,例如 select()

  • params -- 可选字典或字典列表,包含绑定参数值。如果是单个字典,则执行单行;如果是字典列表,则调用“ExecuteMany”。每个字典中的键必须对应于语句中存在的参数名。

  • execution_options -- 执行选项的可选字典,它将与语句执行相关联。此词典可以提供所接受的选项的子集 Connection.execution_options() ,并且还可以提供仅在ORM上下文中理解的附加选项。

  • bind_arguments -- 确定绑定的附加参数字典。可能包括“mapper”、“bind”或其他自定义参数。本词典的内容将传递给 Session.get_bind() 方法。

  • mapper -- 已弃用;请使用bindu参数字典

  • bind -- 已弃用;请使用bindu参数字典

  • **kw -- 已弃用;请使用bindu参数字典

返回

Result 对象。

method sqlalchemy.orm.scoping.scoped_session.expire(instance, attribute_names=None)

使实例上的属性过期。

代表 Session 代表 scoped_session 班级。

将实例的属性标记为过期。下次访问过期属性时,将向 Session 对象的当前事务上下文,以便加载给定实例的所有过期属性。请注意,高度隔离的事务将返回与以前在同一事务中读取的值相同的值,而不考虑该事务外数据库状态的更改。

使中的所有对象过期 Session 同时,使用 Session.expire_all() .

这个 Session 对象的默认行为是在 Session.rollback()Session.commit() 方法,以便可以为新事务加载新状态。为此,请致电 Session.expire() 只有在当前事务中发出非ORM SQL语句的特定情况下才有意义。

参数
  • instance -- 要刷新的实例。

  • attribute_names -- 指示要过期的属性子集的字符串属性名称的可选列表。

参见

刷新/过期 -介绍性材料

Session.expire()

Session.refresh()

Query.populate_existing()

method sqlalchemy.orm.scoping.scoped_session.expire_all()

使此会话中的所有永久实例过期。

代表 Session 代表 scoped_session 班级。

下次访问持久实例上的任何属性时,将使用 Session 对象的当前事务上下文,以便加载给定实例的所有过期属性。请注意,高度隔离的事务将返回与以前在同一事务中读取的值相同的值,而不考虑该事务外数据库状态的更改。

要使这些对象上的单个对象和单个属性过期,请使用 Session.expire() .

这个 Session 对象的默认行为是在 Session.rollback()Session.commit() 方法,以便可以为新事务加载新状态。为此,请致电 Session.expire_all() 当自动提交为 False ,假设事务是独立的。

参见

刷新/过期 -介绍性材料

Session.expire()

Session.refresh()

Query.populate_existing()

method sqlalchemy.orm.scoping.scoped_session.expunge(instance)

移除 instance 由此 Session .

代表 Session 代表 scoped_session 班级。

这将释放对该实例的所有内部引用。将根据 删去 级联规则。

method sqlalchemy.orm.scoping.scoped_session.expunge_all()

从此中删除所有对象实例 Session .

代表 Session 代表 scoped_session 班级。

这相当于呼叫 expunge(obj) 在所有对象上 Session .

method sqlalchemy.orm.scoping.scoped_session.flush(objects=None)

将所有对象更改刷新到数据库。

代表 Session 代表 scoped_session 班级。

将所有挂起的对象创建、删除和修改作为插入、删除、更新等写入数据库。操作由会话的工作单元依赖性求解器自动排序。

数据库操作将在当前事务上下文中发出,并且不会影响事务的状态,除非发生错误,在这种情况下,整个事务将回滚。您可以在事务中随时刷新(),以将更改从python移动到数据库的事务缓冲区。

为了 autocommit 如果会话没有活动的手动事务,flush()将动态创建一个事务,将整个操作集包围到flush中。

参数

objects -- 可选;限制刷新操作仅对给定集合中的元素进行操作。此功能适用于非常狭窄的一组用例,其中可能需要在完全刷新()发生之前对特定对象进行操作。不适用于一般用途。

method sqlalchemy.orm.scoping.scoped_session.get(entity, ident, options=None, populate_existing=False, with_for_update=None, identity_token=None)

根据给定的主键标识符返回实例,或者 None 如果找不到的话。

代表 Session 代表 scoped_session 班级。

例如。::

my_user = session.get(User, 5)

some_object = session.get(VersionedFoo, (5, 10))

some_object = session.get(
    VersionedFoo,
    {"id": 5, "version_id": 10}
)

1.4 新版功能: 已添加 Session.get() ,它是从现在不推荐使用的 Query.get() 方法。

Session.get() 的特殊之处在于它提供了对 Session 。如果给定的主键标识符存在于本地标识映射中,则直接从此集合返回该对象,并且不会发出任何SQL,除非该对象已标记为完全过期。如果不存在,则执行选择以定位该对象。

Session.get() 还将执行检查对象是否出现在身份映射中并标记为过期-发出SELECT以刷新对象并确保行仍然存在。如果不是, ObjectDeletedError 都被养大了。

参数
  • entity -- 映射的类或 Mapper 指示要加载的实体的类型。

  • ident -- 表示主键的标量、元组或字典。对于复合(例如,多列)主键,应该传递元组或字典。对于单列主键,标量调用形式通常是最方便的。如果行的主键是值“5”,则调用如下所示::my_object=session.get(SomeClass,5)元组形式包含的主键值通常按照它们与映射的 Table 对象的主键列,或者如果 Mapper.primary_key 按照该参数使用的顺序使用配置参数。例如,如果行的主键由整数数字“5,10”表示,则调用将如下所示::my_object=session.get(SomeClass,(5,10))字典表单应该包括与主键的每个元素相对应的映射属性名作为键。如果映射的类具有以下属性 idversion_id 作为存储对象主键值的属性,调用如下所示::my_object=session.get(SomeClass,{“id”:5,“version_id”:10})

  • options -- 将应用于查询的加载器选项的可选序列(如果发出)。

  • populate_existing -- 使该方法无条件地发出SQL查询并使用新加载的数据刷新对象,而不管该对象是否已存在。

  • with_for_update -- 可选布尔值 True 指示应使用更新,或者可能是包含标志的字典,以指示选择的更新标志的更具体集合;标志应与的参数匹配 Query.with_for_update() . 取代了 Session.refresh.lockmode 参数。

返回

对象实例,或者 None

method sqlalchemy.orm.scoping.scoped_session.get_bind(mapper=None, clause=None, bind=None, _sa_skip_events=None, _sa_skip_for_implicit_returning=False)

返回一个“绑定”,此 Session 是绑定的。

代表 Session 代表 scoped_session 班级。

“bind”通常是 Engine ,除非 Session 已直接绑定到 Connection .

对于多重绑定或未绑定 Session , the mapperclause 参数用于确定要返回的适当绑定。

注意,“mapper”参数通常在 Session.get_bind() 通过ORM操作调用,例如 Session.query() ,中的每个插入/更新/删除操作 Session.flush() ,电话等。

决议顺序为:

  1. 如果给出映射器并且 Session.binds 如果存在,则首先基于正在使用的映射器,然后基于正在使用的映射类,然后基于中存在的任何基类定位绑定 __mro__ 从更具体的超类到更一般的映射类。

  2. 如果给出条款和 Session.binds 存在,则根据 Table 在给定子句中找到的对象存在于 Session.binds .

  3. 如果 Session.binds 存在,还那个。

  4. 如果给定子句,则尝试返回链接到 MetaData 最终与该条款相关。

  5. 如果给定了映射器,则尝试返回链接到 MetaData 最终与 Table 或映射器映射到的其他可选对象。

  6. 找不到绑定, UnboundExecutionError 提高了。

请注意 Session.get_bind() 方法可以在的用户定义子类上重写 Session 提供任何类型的绑定解决方案。参见中的示例 自定义垂直分区 .

参数

参见

分区策略(例如,每个会话有多个数据库后端)

Session.binds

Session.bind_mapper()

Session.bind_table()

method sqlalchemy.orm.scoping.scoped_session.classmethod identity_key(*args, **kwargs)

返回标识密钥。

代表 Session 代表 scoped_session 班级。

这是的别名 identity_key() .

attribute sqlalchemy.orm.scoping.scoped_session.info

用户可修改字典。

代表 Session 代表 scoped_session 班级。

此字典的初始值可以使用 info 论据 Session 构造函数或 sessionmaker 构造函数或工厂方法。这里的字典总是本地的 Session 并且可以独立于所有其他 Session 物体。

attribute sqlalchemy.orm.scoping.scoped_session.is_active

如果这是真的 Session 不处于“部分回滚”状态。

代表 Session 代表 scoped_session 班级。

在 1.4 版更改: 这个 Session 不再立即开始新事务,因此当 Session 首先实例化。

“部分回滚”状态通常表示 Session 已经失败了 Session.rollback() 方法才能完全回滚事务。

如果这样 Session 根本不在事务中 Session 第一次使用时会自动注册,所以在本例中 Session.is_active 将返回true。

否则,如果 Session 在事务中,并且该事务尚未在内部回滚,则 Session.is_active 也将返回True。

参见

“由于在刷新过程中出现以前的异常,此会话的事务已回滚。”(或类似)

Session.in_transaction()

method sqlalchemy.orm.scoping.scoped_session.is_modified(instance, include_collections=True)

返回 True 如果给定实例具有本地修改的属性。

代表 Session 代表 scoped_session 班级。

此方法检索实例上每个已检测属性的历史记录,并将当前值与其以前提交的值(如果有)进行比较。

实际上,它是在 Session.dirty 集合;对每个属性的网络“脏”状态执行完整测试。

例如。::

return session.is_modified(someobject)

该方法的一些注意事项适用于:

  • 存在于中的实例 Session.dirty 集合可能报告 False 当用这种方法测试时。这是因为对象可能通过属性突变接收到更改事件,因此将其放入 Session.dirty 但最终状态与从数据库加载的状态相同,因此此处不会发生任何净更改。

  • 在应用新值时,如果在接收到新值时属性未被加载或已过期,则标量属性可能没有记录以前设置的值-在这些情况下,假定该属性发生更改,即使其数据库值最终没有净更改。在大多数情况下,当一个集合事件发生时,sqlAlchemy不需要“old”值,因此如果旧值不存在,它会跳过SQL调用的开销,这是基于通常需要更新标量值的假设,而在少数情况下,它不存在的情况下,平均比发出防御性选择的代价要低。

    只有当属性容器具有 active_history 标志设置为 True . 此标志通常为不是简单的多对一的主键属性和标量对象引用设置。要为任意映射列设置此标志,请使用 active_history 争论与 column_property() .

参数
  • instance -- 要测试的映射实例是否存在挂起的更改。

  • include_collections -- 指示操作中是否应包含多值集合。设置为 False 是一种只检测本地基于列的属性(即标量列或多对一外键)的方法,在刷新时将导致此实例的更新。

method sqlalchemy.orm.scoping.scoped_session.merge(instance, load=True, options=None)

将给定实例的状态复制到 Session .

代表 Session 代表 scoped_session 班级。

Session.merge() 检查源实例的主键属性,并尝试将其与会话中相同主键的实例协调。如果在本地找不到,它将尝试基于主键从数据库加载对象,如果找不到,则创建一个新实例。然后将源实例上每个属性的状态复制到目标实例。然后,该方法返回生成的目标实例;原始源实例保持不变,并且与 Session 如果还没有。

如果关联映射为 cascade="merge" .

合并 关于合并的详细讨论。

在 1.1 版更改: - Session.merge() will now reconcile pending objects with overlapping primary keys in the same way as persistent. See session.merge与persistent解决挂起的冲突 for discussion.

参数
  • instance -- 要合并的实例。

  • load -- 布尔值,如果为false, merge() 切换到“高性能”模式,使其放弃发出历史事件以及所有数据库访问。此标志用于将对象的图形传输到 Session 从二级缓存,或将刚加载的对象传输到 Session 由工作线程或进程拥有,而不重新查询数据库。这个 load=False 用例增加了一个警告,即给定对象必须处于“干净”状态,即没有要刷新的挂起更改-即使传入对象与任何 Session . 这样,当合并操作填充本地属性并层叠到相关对象和集合时,可以按原样将值“标记”到目标对象上,而不生成任何历史或属性事件,也不需要将传入数据与可能不是LOA的任何现有相关对象或集合进行协调。德德。结果对象来自 load=False 总是以“干净”的形式生成,因此只有给定的对象也应该是“干净”的才是合适的,否则这就意味着错误地使用了该方法。

  • options -- 加载程序选项的可选序列,这些选项将应用于 Session.get() 当合并操作从数据库加载对象的现有版本时,。。。添加的版本::1.4.24

参见

make_transient_to_detached() - provides for an alternative means of "merging" a single object into the Session

attribute sqlalchemy.orm.scoping.scoped_session.new

在此中标记为“new”的所有实例的集合 Session .

代表 Session 代表 scoped_session 班级。

attribute sqlalchemy.orm.scoping.scoped_session.no_autoflush

返回禁用自动刷新的上下文管理器。

代表 Session 代表 scoped_session 班级。

例如。::

with session.no_autoflush:

    some_object = SomeClass()
    session.add(some_object)
    # won't autoflush
    some_object.related_thing = session.query(SomeRelated).first()

with: 块不会受到查询访问时发生的刷新的影响。这在初始化涉及现有数据库查询的一系列对象时很有用,因为在这些对象中,尚未完成的对象尚未刷新。

method sqlalchemy.orm.scoping.scoped_session.classmethod object_session(instance)

返回 Session 对象所属的。

代表 Session 代表 scoped_session 班级。

这是的别名 object_session() .

method sqlalchemy.orm.scoping.scoped_session.query(*entities, **kwargs)

返回一个新的 Query 与此对应的对象 Session .

代表 Session 代表 scoped_session 班级。

method sqlalchemy.orm.scoping.scoped_session.query_property(query_cls=None)

返回生成 Query 对象与类和当前 Session 当被召唤时。

例如。::

Session = scoped_session(sessionmaker())

class MyClass(object):
    query = Session.query_property()

# after mappers are defined
result = MyClass.query.filter(MyClass.name=='foo').all()

默认情况下生成会话配置的查询类的实例。要重写和使用自定义实现,请提供 query_cls 可赎回的。调用将使用类的映射器作为位置参数和会话关键字参数来调用。

对放置在类上的查询属性的数量没有限制。

method sqlalchemy.orm.scoping.scoped_session.refresh(instance, attribute_names=None, with_for_update=None)

使给定实例上的属性过期并刷新。

代表 Session 代表 scoped_session 班级。

所选属性将首先过期,就像使用时一样 Session.expire() ;然后向数据库发出SELECT语句,用当前事务中可用的当前值刷新面向列的属性。

relationship() 如果面向属性已经被紧急加载到对象上,那么它们也将被立即加载,使用与它们最初加载时相同的紧急加载策略。卸载的关系属性将保持卸载状态,最初延迟加载的关系属性也将保持卸载状态。

1.4 新版功能: -The Session.refresh() 方法还可以刷新紧急加载的属性。

小技巧

在此期间, Session.refresh() 方法能够刷新面向列和面向关系的属性,它的主要关注点是刷新单个实例上的面向列的本地属性。要获得更多开放式“刷新”功能,包括在显式控制关系加载器策略的同时一次刷新多个对象的属性的能力,请使用 populate existing 而不是功能。

请注意,高度隔离的事务将返回与先前在同一事务中读取的值相同的值,而不考虑该事务外部数据库状态的更改。刷新属性通常仅在尚未访问数据库行的事务开始时才有意义。

参数
  • attribute_names -- 可选的。字符串属性名的可ITerable集合,指示要刷新的属性子集。

  • with_for_update -- 可选布尔值 True 指示应使用更新,或者可能是包含标志的字典,以指示选择的更新标志的更具体集合;标志应与的参数匹配 Query.with_for_update() . 取代了 Session.refresh.lockmode 参数。

参见

刷新/过期 -介绍性材料

Session.expire()

Session.expire_all()

填充现有 -允许任何ORM查询按照正常加载的方式刷新对象。

method sqlalchemy.orm.scoping.scoped_session.remove()

处理电流 Session ,如果存在的话。

这是第一个电话 Session.close() 当前的方法 Session ,释放仍保留的任何现有事务/连接资源;事务将被回滚。这个 Session 然后被丢弃。在同一范围内的下一次使用时, scoped_session 会产生新的 Session 对象。

method sqlalchemy.orm.scoping.scoped_session.rollback()

回滚正在进行的当前事务。

代表 Session 代表 scoped_session 班级。

如果没有正在进行的事务,则此方法是传递。

1.x-style 如果没有有效的嵌套事务,则此方法回滚最顶层的数据库事务;如果有嵌套事务生效,则回滚到当前嵌套事务。

什么时候? 2.0-style 使用通过 Session.future 标志时,该方法始终回滚最顶层的数据库事务,丢弃任何可能正在进行的嵌套事务。

参见

回滚

管理交易

method sqlalchemy.orm.scoping.scoped_session.scalar(statement, params=None, execution_options={}, bind_arguments=None, **kw)

执行语句并返回标量结果。

代表 Session 代表 scoped_session 班级。

用法和参数与的相同 Session.execute() ;返回结果是一个标量Python值。

method sqlalchemy.orm.scoping.scoped_session.scalars(statement, params=None, execution_options={}, bind_arguments=None, **kw)

执行语句并以标量形式返回结果。

代表 Session 代表 scoped_session 班级。

用法和参数与的相同 Session.execute() ;返回结果为 ScalarResult 将返回单个元素而不是 Row 对象。

返回

一个 ScalarResult 对象

1.4.24 新版功能.

attribute sqlalchemy.orm.scoping.scoped_session.session_factory = None

这个 session_factory provided to _ _ Init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu当新的非作用域 :class:.Session` 或 Connection 需要数据库。

class sqlalchemy.util.ScopedRegistry(createfunc, scopefunc)

一种注册表,它可以在“作用域”函数的基础上存储单个类的一个或多个实例。

对象实现 __call__ 作为“getter”,所以打电话给 myregistry() 将为当前作用域返回包含的对象。

参数
  • createfunc -- 返回要放置在注册表中的新对象的可调用文件

  • scopefunc -- 将返回一个键以存储/检索对象的可调用文件。

method sqlalchemy.util.ScopedRegistry.__init__(createfunc, scopefunc)

构建新的 ScopedRegistry .

参数
  • createfunc -- 一个创建函数,如果当前作用域不存在,它将为当前作用域生成一个新值。

  • scopefunc -- 返回表示当前作用域(如当前线程标识符)的哈希标记的函数。

method sqlalchemy.util.ScopedRegistry.clear()

清除当前范围(如果有)。

method sqlalchemy.util.ScopedRegistry.has()

如果对象存在于当前作用域中,则返回true。

method sqlalchemy.util.ScopedRegistry.set(obj)

设置当前作用域的值。

class sqlalchemy.util.ThreadLocalRegistry(createfunc)

A ScopedRegistry 使用A threading.local() 用于存储的变量。

类签名

class sqlalchemy.util.ThreadLocalRegistry (sqlalchemy.util.ScopedRegistry)