SqlAlchemy 2.0 中文文档(四十五)(2)https://developer.aliyun.com/article/1563078
断开处理 - 乐观
当不使用悲观处理,并且在事务中连接使用期间数据库关闭和/或重新启动时,处理陈旧/关闭连接的另一种方法是让 SQLAlchemy 在断开连接时处理,此时池中的所有连接都将被作废,意味着它们被假定为陈旧的,并将在下次检出时刷新。此行为假定与 Pool
一起使用 Engine
。Engine
具有可以检测到断开连接事件并自动刷新池的逻辑。
当 Connection
尝试使用 DBAPI 连接,并引发与“断开”事件对应的异常时,连接将被作废。然后,Connection
调用 Pool.recreate()
方法,有效地作废所有当前未检出的连接,以便在下一次检出时用新连接替换它们。下面的代码示例说明了这个流程:
from sqlalchemy import create_engine, exc e = create_engine(...) c = e.connect() try: # suppose the database has been restarted. c.execute(text("SELECT * FROM table")) c.close() except exc.DBAPIError as e: # an exception is raised, Connection is invalidated. if e.connection_invalidated: print("Connection was invalidated!") # after the invalidate event, a new connection # starts with a new Pool c = e.connect() c.execute(text("SELECT * FROM table"))
上面的示例说明,在检测到断开连接事件后,不需要任何特殊干预来刷新池,池在此后会正常运行。然而,在数据库不可用事件发生时,每个正在使用的连接都会引发一个数据库异常。在使用 ORM 会话的典型 Web 应用程序中,上述情况将对应于一个请求失败并返回 500 错误,然后 Web 应用程序在此之后会正常继续运行。因此,这种方法是“乐观的”,不预期频繁地重启数据库。
设置池回收
可以增强“乐观”方法的另一个设置是设置池回收参数。该参数防止池使用已经存在一段时间的特定连接,适用于数据库后端(如 MySQL),该后端在一段特定时间后会自动关闭已经过时的连接:
from sqlalchemy import create_engine e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", pool_recycle=3600)
在上述设置中,任何已经打开超过一小时的 DBAPI 连接将在下一次检出时被作废并替换。请注意,作废仅在检出时发生 - 不会作用于任何处于已检出状态的连接。pool_recycle
是 Pool
本身的一个函数,与是否使用 Engine
无关。 #### 设置池回收
可以增强“乐观”方法的另一个设置是设置池回收参数。该参数防止池使用已经存在一段时间的特定连接,适用于数据库后端(如 MySQL),该后端在一段特定时间后会自动关闭已经过时的连接:
from sqlalchemy import create_engine e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", pool_recycle=3600)
在上述设置中,任何已经打开超过一小时的 DBAPI 连接将在下一次检出时被作废并替换。请注意,作废仅在检出时发生 - 不会作用于任何处于已检出状态的连接。pool_recycle
是 Pool
本身的一个函数,与是否使用 Engine
无关。
更多关于作废的内容
Pool
提供“连接失效”服务,允许显式失效连接以及在确定使连接不可用的条件下自动失效。
“失效”意味着特定的 DBAPI 连接从池中移除并丢弃。如果不清楚连接本身是否关闭,则在此连接上调用.close()
方法,但如果此方法失败,则记录异常但操作仍继续。
在使用Engine
时,Connection.invalidate()
方法通常是显式失效的入口点。其他可能使 DBAPI 连接失效的条件包括:
- 例如
OperationalError
这样的 DBAPI 异常,在调用connection.execute()
等方法时引发,被检测为所谓的“断开”条件。由于 Python DBAPI 没有确定异常性质的标准系统,所有 SQLAlchemy 方言都包括一个名为is_disconnect()
的系统,它将检查异常对象的内容,包括字符串消息和其中包含的任何潜在错误代码,以确定此异常是否指示连接不再可用。如果是这种情况,将调用_ConnectionFairy.invalidate()
方法,然后丢弃 DBAPI 连接。 - 当连接返回到池中,并调用
connection.rollback()
或connection.commit()
方法时,根据池的“返回时重置”行为,抛出异常。将最后尝试在连接上调用.close()
方法,然后将其丢弃。 - 当实现
PoolEvents.checkout()
的监听器引发DisconnectionError
异常时,表示连接将无法使用,需要进行新的连接尝试。
所有发生的失效将调用PoolEvents.invalidate()
事件。
支持断开情景的新数据库错误代码
SQLAlchemy 方言(dialects)中都包含一个名为 is_disconnect()
的程序,当遇到 DBAPI 异常时会调用该程序。DBAPI 异常对象会传递给这个方法,在这里,方言特定的启发法则将确定接收到的错误代码是否指示数据库连接已被“断开”,或者处于其他无法使用的状态,表明应该重新使用该连接。此处应用的启发式方法可以使用 DialectEvents.handle_error()
事件钩子进行自定义,通常是通过所属的 Engine
对象建立的。使用此钩子,所有发生的错误都会传递一个称为 ExceptionContext
的上下文对象。自定义事件钩子可以控制特定错误是否应该被视为“断开”情况,以及此断开是否应该导致整个连接池无效化。
例如,要添加支持将 Oracle 错误代码 DPY-1001
和 DPY-4011
视为断开代码进行处理,需要在创建引擎后应用一个事件处理程序:
import re from sqlalchemy import create_engine engine = create_engine("oracle://scott:tiger@dnsname") @event.listens_for(engine, "handle_error") def handle_exception(context: ExceptionContext) -> None: if not context.is_disconnect and re.match( r"^(?:DPI-1001|DPI-4011)", str(context.original_exception) ): context.is_disconnect = True return None
上述错误处理函数将对所有引发的 Oracle 错误进行调用,包括在使用 pool pre ping 特性时捕获的错误,用于依赖于断开连接错误处理的后端(在 2.0 版本中新增)。
另见
DialectEvents.handle_error()
使用 FIFO vs. LIFO
QueuePool
类特征一个名为 QueuePool.use_lifo
的标志,也可以通过标志 create_engine.pool_use_lifo
在 create_engine()
中访问。将此标志设置为 True
会导致池的“队列”行为变为“堆栈”,例如,返回到池中的最后一个连接将在下一次请求中首先被使用。与池的先入先出长期行为相反,后者产生一个轮转效果,依次使用池中的每个连接,LIFO 模式允许多余的连接在池中保持空闲,从而允许服务器端超时方案关闭这些连接。FIFO 和 LIFO 的区别基本上是池是否在空闲期间保持一组完整的连接准备就绪:
engine = create_engine("postgreql://", pool_use_lifo=True, pool_pre_ping=True)
此外,我们还使用了create_engine.pool_pre_ping
标志,以便由服务器端关闭的连接被连接池优雅地处理,并替换为新连接。
注意,此标志仅适用于QueuePool
的使用。
版本 1.3 中的新功能。
另请参阅
处理断开连接
使用连接池与多进程或 os.fork()
在使用连接池时(通过create_engine()
创建的Engine
),至关重要的是,不要共享池化的连接给分叉的进程。 TCP 连接表示为文件描述符,通常跨进程边界工作,这意味着这将导致在两个或更多完全独立的 Python 解释器状态的代表性之间并发访问文件描述符。
根据驱动程序和操作系统的具体情况,此处出现的问题范围从不起作用的连接到被多个进程同时使用的套接字连接,导致消息中断(后者通常是最常见的情况)。
SQLAlchemy Engine
对象指的是现有数据库连接的连接池。因此,当此对象被复制到子进程时,目标是确保不会携带任何数据库连接。有四种一般方法来解决这个问题:
- 使用
NullPool
禁用连接池。这是最简单的、一次性的系统,防止Engine
重复使用任何连接:
from sqlalchemy.pool import NullPool engine = create_engine("mysql+mysqldb://user:pass@host/dbname", poolclass=NullPool)
- 在子进程的初始化阶段调用
Engine.dispose()
,传递值为False
的Engine.dispose.close
参数。这样新进程就不会触及任何父进程的连接,而是会以新的连接开始。这是推荐的方法:
from multiprocessing import Pool engine = create_engine("mysql+mysqldb://user:pass@host/dbname") def run_in_process(some_data_record): with engine.connect() as conn: conn.execute(text("...")) def initializer(): """ensure the parent proc's database connections are not touched in the new connection pool""" engine.dispose(close=False) with Pool(10, initializer=initializer) as p: p.map(run_in_process, data)
- 版本 1.4.33 中的新功能:添加了
Engine.dispose.close
参数,以允许在子进程中替换连接池,而不会干扰父进程使用的连接。 - 在创建子进程之前直接调用
Engine.dispose()
。这也将导致子进程以新的连接池启动,同时确保父连接不会传递给子进程:
engine = create_engine("mysql://user:pass@host/dbname") def run_in_process(): with engine.connect() as conn: conn.execute(text("...")) # before process starts, ensure engine.dispose() is called engine.dispose() p = Process(target=run_in_process) p.start()
- 可以向连接池应用事件处理程序,以测试跨进程边界共享的连接,并使其无效:
from sqlalchemy import event from sqlalchemy import exc import os engine = create_engine("...") @event.listens_for(engine, "connect") def connect(dbapi_connection, connection_record): connection_record.info["pid"] = os.getpid() @event.listens_for(engine, "checkout") def checkout(dbapi_connection, connection_record, connection_proxy): pid = os.getpid() if connection_record.info["pid"] != pid: connection_record.dbapi_connection = connection_proxy.dbapi_connection = None raise exc.DisconnectionError( "Connection record belongs to pid %s, " "attempting to check out in pid %s" % (connection_record.info["pid"], pid) )
- 在上面,我们使用了类似于断开处理 - 悲观中描述的方法来处理在不同父进程中起源的 DBAPI 连接,将其视为“无效”连接,强制池回收连接记录以建立新连接。
上述策略将适用于在进程之间共享Engine
的情况。仅仅上述步骤并不足以处理在进程边界共享特定Connection
的情况;最好将特定Connection
的范围局限于单个进程(和线程)。直接跨进程共享任何类型的进行中的事务状态,比如已开始事务并引用活动Connection
实例的 ORM Session
对象,也不受支持;最好在新进程中创建新的Session
对象。
直接使用池实例
可以直接使用池实现而不需要引擎。这可用于只希望使用池行为而不需要所有其他 SQLAlchemy 功能的应用程序。在下面的示例中,使用create_pool_from_url()
获取MySQLdb
方言的默认池:
from sqlalchemy import create_pool_from_url my_pool = create_pool_from_url( "mysql+mysqldb://", max_overflow=5, pool_size=5, pre_ping=True ) con = my_pool.connect() # use the connection ... # then close it con.close()
如果未指定要创建的池的类型,则将使用该方言的默认池。可以直接指定poolclass
参数,如下例所示:
from sqlalchemy import create_pool_from_url from sqlalchemy import NullPool my_pool = create_pool_from_url("mysql+mysqldb://", poolclass=NullPool)
API 文档 - 可用的池实现
对象名称 | 描述 |
_ConnectionFairy | 代理一个 DBAPI 连接,并提供返回引用支持。 |
_ConnectionRecord | 维护连接池中的位置,引用一个池化连接。 |
AssertionPool | 允许每次最多只有一个已签出连接的Pool 。 |
异步适配队列池 | 队列池 的一个适用于 asyncio 的版本。 |
连接池条目 | 代表池 实例的个别数据库连接的对象的接口。 |
管理连接 | 用于两个连接管理接口池代理连接 和连接池条目 的通用基类。 |
空池 | 不对连接进行池化的池。 |
池 | 连接池的抽象基类。 |
池代理连接 | 用于PEP 249 DBAPI 连接的类似连接的适配器,其中包括特定于池 实现的附加方法。 |
队列池 | 对打开连接数量施加限制的池 。 |
单例线程池 | 每个线程维护一个连接的池。 |
静态池 | 用于所有请求的恰好一个连接的池。 |
class sqlalchemy.pool.Pool
连接池的抽象基类。
成员
init(), connect(), dispose(), recreate()
类签名
类sqlalchemy.pool.Pool
(sqlalchemy.log.Identified
, sqlalchemy.event.registry.EventTarget
)的签名
method __init__(creator: _CreatorFnType | _CreatorWRecFnType, recycle: int = -1, echo: log._EchoFlagType = None, logging_name: str | None = None, reset_on_return: _ResetStyleArgType = True, events: List[Tuple[_ListenerFnType, str]] | None = None, dialect: _ConnDialect | Dialect | None = None, pre_ping: bool = False, _dispatch: _DispatchCommon[Pool] | None = None)
构建一个池。
参数:
creator
– 一个可调用的函数,返回一个 DB-API 连接对象。该函数将带有参数调用。recycle
– 如果设置为除-1 以外的值,则连接回收之间的秒数,这意味着在检出时,如果超过此超时,则连接将被关闭并替换为新打开的连接。默认为-1。logging_name
– 用于“sqlalchemy.pool”记录器中生成的日志记录的“name”字段的字符串标识符。默认为对象 id 的十六进制字符串。echo
–
如果为真,则连接池将记录信息输出,例如当连接失效时以及当连接被回收时,默认日志处理程序为sys.stdout
。如果设置为字符串"debug"
,日志将包括池检出和检入。Pool.echo
参数也可以通过使用create_engine.echo_pool
参数从create_engine()
调用中设置。
另请参阅
配置日志记录 - 如何配置日志记录的更多详细信息。reset_on_return
–确定在将连接返回到池中时执行的步骤,这些步骤否则不会由Connection
处理。可以通过create_engine()
通过create_engine.pool_reset_on_return
参数来使用。Pool.reset_on_return
可以有以下任何值:
"rollback"
- 在连接上调用 rollback(),释放锁和事务资源。这是默认值。绝大多数情况下应该保持此值不变。"commit"
- 在连接上调用 commit(),释放锁和事务资源。在某些情况下,如微软 SQL Server,如果发出了 commit,则可能需要提交。然而,这个值比 ‘rollback’ 更危险,因为任何存在于事务中的数据更改都会无条件地提交。None
- 在连接上不执行任何操作。如果数据库/DBAPI 在所有时刻都以纯“自动提交”模式工作,或者使用PoolEvents.reset()
事件处理程序建立了自定义重置处理程序,则此设置可能是合适的。True
- 与 ‘rollback’ 相同,这是为了向后兼容而存在的。False
- 与 None 相同,这是为了向后兼容而存在的。
- 为了进一步定制返回时的重置,可以使用
PoolEvents.reset()
事件钩子,该钩子可以在重置时执行任何所需的连接活动。
另请参阅
返回时重置PoolEvents.reset()
events
– 一个 2-元组列表,每个元组的形式为(callable, target)
,将在构造时传递给listen()
。此处提供是为了在应用方言级别的监听器之前,可以通过create_engine()
分配事件监听器。dialect
– 一个处理 DBAPI 连接的回滚(rollback())、关闭(close())或提交(commit())工作的Dialect
。如果省略,将使用内置的“存根”方言。使用create_engine()
的应用程序不应使用此参数,因为它由引擎创建策略处理。pre_ping
–
如果为 True,则池将在检出连接时发出“ping”(通常为“SELECT 1”,但是是特定于方言的),以测试连接是否活动。如果不活动,则连接将被透明地重新连接,并在成功后,所有在该时间戳之前建立的其他池连接将无效。还需要传递一个方言以解释断开连接错误。
1.2 版本中新增。
method connect() → PoolProxiedConnection
从池中返回一个 DBAPI 连接。
连接被检测工具检测,以便在调用其 close()
方法时,连接将被返回到池中。
method dispose() → None
处置此池。
此方法可能导致仍处于检出状态的连接保持打开状态,因为它仅影响池中处于空闲状态的连接。
另请参见
Pool.recreate()
method recreate() → Pool
返回一个新的 Pool
,与此相同类的池,并配置相同的创建参数。
此方法与 dispose()
结合使用,用于关闭整个 Pool
并在其位置创建一个新的 Pool。
class sqlalchemy.pool.QueuePool
施加对打开连接数量的限制的 Pool
。
QueuePool
是除了 SQLite 的 :memory:
数据库之外,所有 Engine
对象的默认池实现。
QueuePool
类与 asyncio 不兼容,并且 create_async_engine()
。当使用 create_async_engine()
时,如果没有指定其他类型的池,则会自动使用 AsyncAdaptedQueuePool
类。
另请参见
AsyncAdaptedQueuePool
成员
init(), dispose(), recreate()
类签名
类sqlalchemy.pool.QueuePool
(sqlalchemy.pool.base.Pool
)
method __init__(creator: _CreatorFnType | _CreatorWRecFnType, pool_size: int = 5, max_overflow: int = 10, timeout: float = 30.0, use_lifo: bool = False, **kw: Any)
构造一个 QueuePool。
参数:
creator
– 一个可调用函数,返回一个与Pool.creator
相同的 DB-API 连接对象。pool_size
– 要维护的池的大小,默认为 5。这是将持续保留在池中的最大连接数。请注意,池开始时没有连接;一旦请求了这个数量的连接,这个数量的连接将保持不变。pool_size
可设置为 0,表示没有大小限制;要禁用池化,请使用NullPool
。max_overflow
– 池的最大溢出大小。当已签出连接的数量达到 pool_size 中设置的大小时,将返回额外的连接,直到达到此限制为止。当这些额外的连接返回到池中时,它们将被断开并丢弃。因此,池允许的同时连接数是 pool_size + max_overflow,池允许的“睡眠”连接总数是 pool_size。max_overflow 可设置为-1,表示无溢出限制;不会对并发连接的总数设置限制。默认为 10。timeout
– 在放弃返回连接之前等待的秒数。默认为 30.0。这可以是一个浮点数,但受 Python 时间函数的限制,可能不可靠,精度在几十毫秒内。use_lifo
–
在检索连接时使用 LIFO(后进先出)而不是 FIFO(先进先出)。使用 LIFO,服务器端的超时方案可以在非高峰使用期间减少使用的连接数量。在规划服务器端超时时,请确保使用回收或预检查策略来优雅地处理陈旧的连接。
新功能,版本 1.3。
另请参阅
使用 FIFO vs. LIFO
处理断开连接**kw
– 其他关键字参数,包括Pool.recycle
、Pool.echo
、Pool.reset_on_return
等,将传递给Pool
构造函数。
method dispose() → None
释放此池。
此方法可能导致已签出的连接保持打开状态,因为它只影响池中处于空闲状态的连接。
另请参阅
Pool.recreate()
method recreate() → QueuePool
返回一个新的Pool
,与此对象相同类别的对象,并配置相同的创建参数。
此方法与 dispose()
结合使用,以关闭整个 Pool
并在其位置创建一个新的池。
class sqlalchemy.pool.AsyncAdaptedQueuePool
QueuePool
的一个与 asyncio 兼容的版本。
当使用从 create_async_engine()
生成的 AsyncEngine
引擎时,默认使用此池。它使用了一个与 asyncio 兼容的队列实现,不使用 threading.Lock
。
AsyncAdaptedQueuePool
的参数和操作与 QueuePool
相同。
类签名
class sqlalchemy.pool.AsyncAdaptedQueuePool
(sqlalchemy.pool.impl.QueuePool
)
class sqlalchemy.pool.SingletonThreadPool
每个线程维护一个连接的池。
每个线程维护一个连接,永远不会将连接移动到其创建的线程之外。
警告
SingletonThreadPool
将对超出 pool_size
大小设置的任意连接调用 .close()
,例如,如果使用的唯一 线程标识 大于 pool_size
所指定的数量。此清理是非确定性的,并且不会因连接是否与这些线程标识关联并当前正在使用而受到影响。
SingletonThreadPool
在未来的版本中可能会得到改进,但在当前状态下,它通常仅用于使用 SQLite 的 :memory:
数据库的测试场景,并不建议用于生产环境。
SingletonThreadPool
类 不兼容 asyncio 和 create_async_engine()
。
选项与 Pool
相同,以及:
参数:
pool_size – 同时维护连接的线程数。默认为五。
当使用基于内存的数据库时,SQLite 方言会自动使用 SingletonThreadPool
。请参阅 SQLite。
成员
connect(), dispose(), recreate()
类签名
类sqlalchemy.pool.SingletonThreadPool
(sqlalchemy.pool.base.Pool
)
method connect() → PoolProxiedConnection
从池中返回一个 DBAPI 连接。
连接被仪器化,这样当调用其close()
方法时,连接将被返回到池中。
method dispose() → None
释放此池。
method recreate() → SingletonThreadPool
返回一个新的Pool
,与此相同类别,并使用相同的创建参数配置。
此方法与dispose()
结合使用,关闭整个Pool
并创建一个新的替代品。
class sqlalchemy.pool.AssertionPool
一个允许在任何给定时间最多有一个已检出连接的Pool
。
如果同时检出了多个连接,则会引发异常。 对于调试使用比期望的连接更多的代码很有用。
AssertionPool
类与 asyncio 和create_async_engine()
兼容。
成员
dispose(), recreate()
类签名
类sqlalchemy.pool.AssertionPool
(sqlalchemy.pool.base.Pool
)
method dispose() → None
释放此池。
此方法使得已检出连接保持打开的可能性,因为它仅影响池中处于空闲状态的连接。
另请参阅
Pool.recreate()
method recreate() → AssertionPool
返回一个新的Pool
,与此相同类别,并使用相同的创建参数配置。
此方法与dispose()
结合使用,关闭整个Pool
并创建一个新的替代品。
class sqlalchemy.pool.NullPool
不池化连接的池。
反而,它会逐个连接地打开和关闭底层的 DB-API 连接。
此池实现不支持与重新连接相关的函数,如recycle
和连接失效,因为没有连接持续存在。
NullPool
类与asyncio 和create_async_engine()
兼容。
成员
dispose(), recreate()
类签名
类sqlalchemy.pool.NullPool
(sqlalchemy.pool.base.Pool
)
method dispose() → None
处置此池。
这种方法留下了已检出连接保持打开的可能性,因为它只影响池中处于空闲状态的连接。
另见
Pool.recreate()
method recreate() → NullPool
返回一个新的Pool
,与此相同的类,并配置相同的创建参数。
此方法与dispose()
一起使用,以关闭整个Pool
并在其位置创建一个新的。
class sqlalchemy.pool.StaticPool
一个连接池,用于所有请求。
重新连接相关的函数,如recycle
和连接失效(也用于支持自动重新连接),目前仅部分支持,可能不会产生良好的结果。
StaticPool
类与asyncio 和create_async_engine()
兼容。
成员
dispose(), recreate()
类签名
类sqlalchemy.pool.StaticPool
(sqlalchemy.pool.base.Pool
)
method dispose() → None
处置此池。
这种方法留下了已检出连接保持打开的可能性,因为它只影响池中处于空闲状态的连接。
另见
Pool.recreate()
method recreate() → StaticPool
返回一个新的Pool
,与此相同的类,并配置相同的创建参数。
此方法与dispose()
一起使用,以关闭整个Pool
并在其位置创建一个新的。
class sqlalchemy.pool.ManagesConnection
两个连接管理接口的共同基类PoolProxiedConnection
和ConnectionPoolEntry
。
这两个对象通常通过连接池事件钩子在公共 API 中公开,详见 PoolEvents
。
成员
dbapi_connection, driver_connection, info, invalidate(), record_info
新版本 2.0 中新增。
attribute dbapi_connection: DBAPIConnection | None
跟踪的实际 DBAPI 连接的引用。
这是一个PEP 249-兼容对象,对于传统的同步式方言,由使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是 SQLAlchemy 方言本身提供的适配器对象;底层 asyncio 对象可通过 ManagesConnection.driver_connection
属性获得。
SQLAlchemy 对 DBAPI 连接的接口基于 DBAPIConnection
协议对象
另请参阅
ManagesConnection.driver_connection
在使用引擎时如何获取原始 DBAPI 连接?
attribute driver_connection: Any | None
Python DBAPI 或数据库驱动程序中使用的“驱动程序级别”连接对象。
对于传统的PEP 249 DBAPI 实现,此对象将与 ManagesConnection.dbapi_connection
的对象相同。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如 asyncpg.Connection
对象,该对象不会具有标准的 pep-249 方法。
新版本 1.4.24 中新增。
另请参阅
ManagesConnection.dbapi_connection
在使用引擎时如何获取原始 DBAPI 连接?
attribute info
与此 ManagesConnection
实例引用的底层 DBAPI 连接相关联的信息字典,允许将用户定义的数据与连接关联起来。
此字典中的数据在 DBAPI 连接本身的生命周期内是持久的,包括池检入和检出期间。当连接无效并替换为新连接时,此字典将被清除。
对于一个未关联ConnectionPoolEntry
的PoolProxiedConnection
实例,例如如果它被分离,该属性返回一个仅限于该ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
另请参阅
ManagesConnection.record_info
method invalidate(e: BaseException | None = None, soft: bool = False) → None
将受管连接标记为无效。
参数:
e
– 指示失效原因的异常对象。soft
– 如果为 True,则连接不会关闭;相反,此连接将在下次检出时被回收。
另请参阅
更多关于失效化的信息
attribute record_info
与此ManagesConnection
关联的持久信息字典。
与ManagesConnection.info
字典不同,此字典的生命周期与拥有它的ConnectionPoolEntry
相同;因此,此字典将在重新连接和特定连接池条目的失效化过程中持续存在。
对于一个未关联ConnectionPoolEntry
的PoolProxiedConnection
实例,例如如果它被分离,该属性返回 None。与永不为 None 的ManagesConnection.info
字典形成对比。
另请参阅
ManagesConnection.info
class sqlalchemy.pool.ConnectionPoolEntry
代表在Pool
实例上维护单个数据库连接的对象的接口。
ConnectionPoolEntry
对象表示池中特定连接的长期维护,包括使该连接过期或无效以将其替换为新连接,这将继续由同一ConnectionPoolEntry
实例维护。与PoolProxiedConnection
相比,后者是短期的,每次检出的连接管理器,该对象的寿命为连接池中特定“槽位”的寿命。
当交付给连接池事件钩子时,ConnectionPoolEntry
对象主要对公共 API 代码可见,例如PoolEvents.connect()
和 PoolEvents.checkout()
。
2.0 版新功能:ConnectionPoolEntry
为_ConnectionRecord
内部类提供了公共界面。
成员
close(), dbapi_connection, driver_connection, in_use, info, invalidate(), record_info
类签名
类sqlalchemy.pool.ConnectionPoolEntry
(sqlalchemy.pool.base.ManagesConnection
)
method close() → None
关闭此连接池条目管理的 DBAPI 连接。
attribute dbapi_connection: DBAPIConnection | None
对正在跟踪的实际 DBAPI 连接的引用。
这是一个PEP 249-兼容对象,对于传统的同步样式方言,由使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是 SQLAlchemy 方言本身提供的适配器对象;基础 asyncio 对象可通过ManagesConnection.driver_connection
属性获得。
SQLAlchemy 对 DBAPI 连接的接口基于DBAPIConnection
协议对象
另请参阅
ManagesConnection.driver_connection
当使用引擎时,如何获取原始的 DBAPI 连接?
attribute driver_connection: Any | None
由 Python DBAPI 或数据库驱动程序使用的“驱动程序级”连接对象。
对于传统的PEP 249 DBAPI 实现,该对象将与 ManagesConnection.dbapi_connection
相同。对于异步数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如 asyncpg.Connection
对象,该对象不具有标准的 pep-249 方法。
新版本 1.4.24 中的新增内容。
另请参阅
ManagesConnection.dbapi_connection
当使用引擎时,如何获取原始的 DBAPI 连接?
attribute in_use
如果连接当前正在被检出,则返回 True
attribute info
继承自 ManagesConnection.info
属性
与此 ManagesConnection
实例引用的底层 DBAPI 连接关联的信息字典,允许将用户定义的数据与连接关联起来。
此字典中的数据对于 DBAPI 连接本身的生命周期是持久的,包括池中的检入和检出。当连接被失效并替换为新连接时,该字典将被清除。
对于不与 ConnectionPoolEntry
关联的 PoolProxiedConnection
实例,例如如果它被分离了,该属性将返回一个局部于该 ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
另请参阅
ManagesConnection.record_info
method invalidate(e: BaseException | None = None, soft: bool = False) → None
继承自 ManagesConnection.invalidate()
方法
将受管理的连接标记为失效。
参数:
e
– 表示失效原因的异常对象。soft
– 如果为 True,则不会关闭连接;相反,该连接将在下次检出时被回收。
另请参阅
更多关于失效化的内容
attribute record_info
继承自 ManagesConnection
的 ManagesConnection.record_info
属性
与此ManagesConnection
关联的持久信息字典。
与ManagesConnection.info
字典不同,此字典的生命周期与拥有它的ConnectionPoolEntry
相同;因此,对于连接池中特定条目的重新连接和连接失效,此字典将持续存在。
对于未与ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如如果它被分离,该属性返回 None。与永不为 None 的ManagesConnection.info
字典形成对比。
另请参阅
ManagesConnection.info
class sqlalchemy.pool.PoolProxiedConnection
用于PEP 249 DBAPI 连接的类似连接适配器,包括特定于Pool
实现的附加方法。
PoolProxiedConnection
是内部_ConnectionFairy
实现对象的公共接口;熟悉_ConnectionFairy
的用户可以将此对象视为等效。
新版本 2.0 中:PoolProxiedConnection
提供了_ConnectionFairy
内部类的公共接口。
成员
close(), dbapi_connection, detach(), driver_connection, info, invalidate(), is_detached, is_valid, record_info
类签名
类sqlalchemy.pool.PoolProxiedConnection
(sqlalchemy.pool.base.ManagesConnection
)
method close() → None
将此连接释放回到池中。
PoolProxiedConnection.close()
方法覆盖了PEP 249的.close()
方法,改变了其行为,使其释放代理连接返回到连接池。
将连接释放到池中后,连接在 Python 进程中是否保持“打开”并保留在池中,还是实际关闭并从 Python 进程中删除,取决于正在使用的池实现及其配置和当前状态。
attribute dbapi_connection: DBAPIConnection | None
对被跟踪的实际 DBAPI 连接的引用。
这是一个PEP 249兼容对象,对于传统的同步风格方言,由使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是 SQLAlchemy 方言本身提供的适配器对象;底层的 asyncio 对象可通过ManagesConnection.driver_connection
属性访问。
SQLAlchemy 的 DBAPI 连接接口基于DBAPIConnection
协议对象
另请参阅
ManagesConnection.driver_connection
在使用 Engine 时,如何获取原始的 DBAPI 连接?
method detach() → None
将此连接与其连接池分离。
这意味着当关闭连接时,连接将不再返回到池中,而是被实际关闭。关联的ConnectionPoolEntry
与此 DBAPI 连接解除关联。
请注意,在分离后,由池实现强加的任何整体连接限制约束可能会被违反,因为分离的连接从池的知识和控制中移除。
attribute driver_connection: Any | None
Python DBAPI 或数据库驱动程序使用的“驱动程序级别”的连接对象。
对于传统的PEP 249 DBAPI 实现,该对象将与ManagesConnection.dbapi_connection
的对象相同。对于一个 asyncio 数据库驱动程序,这将是该驱动程序使用的最终的“连接”对象,例如asyncpg.Connection
对象,它不会具有标准的 pep-249 方法。
版本 1.4.24 中的新功能。
另请参阅
ManagesConnection.dbapi_connection
在使用 Engine 时如何获取原始的 DBAPI 连接?
attribute info
继承自 ManagesConnection
的 ManagesConnection.info
属性
与此ManagesConnection
实例引用的底层 DBAPI 连接相关联的信息字典,允许将用户定义的数据与连接关联起来。
这个字典中的数据在整个 DBAPI 连接的生命周期内是持久的,包括连接池的签入和签出。当连接失效并被新连接替换时,该字典将被清除。
对于不与ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如如果它被分离,该属性返回一个仅限于该ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
另请参阅
ManagesConnection.record_info
method invalidate(e: BaseException | None = None, soft: bool = False) → None
继承自 ManagesConnection
的 ManagesConnection.invalidate()
方法
将托管连接标记为失效。
参数:
e
– 一个表示失效原因的异常对象。soft
– 如果为 True,则连接不会关闭;相反,此连接将在下次签出时被回收。
另请参阅
更多关于失效的信息
attribute is_detached
如果此PoolProxiedConnection
已从其池中分离,则返回 True。
attribute is_valid
如果此PoolProxiedConnection
仍指向活动的 DBAPI 连接,则返回 True。
attribute record_info
继承自 ManagesConnection
的 ManagesConnection.record_info
属性
与此ManagesConnection
相关联的持久信息字典。
与ManagesConnection.info
字典不同,此字典的生命周期是由拥有它的ConnectionPoolEntry
决定的;因此,这个字典将在连接池中的特定条目的重新连接和连接失效时保持不变。
对于未关联到ConnectionPoolEntry
的PoolProxiedConnection
实例,例如如果它是分离的,则该属性返回 None。与永远不会为 None 的ManagesConnection.info
字典相比。
另请参阅
ManagesConnection.info
class sqlalchemy.pool._ConnectionFairy
代理 DBAPI 连接并提供解引用支持。
这是Pool
实现内部使用的对象,用于为该Pool
提供上下文管理,以由该Pool
提供的 DBAPI 连接。该类的公共接口由PoolProxiedConnection
类描述。请参阅该类以获取公共 API 详细信息。
名称“fairy”灵感来自于_ConnectionFairy
对象的生命周期是短暂的,因为它仅在从池中检出的特定 DBAPI 连接的长度内存在,并且作为透明代理,它大部分时间是不可见的。
另请参阅
PoolProxiedConnection
ConnectionPoolEntry
类签名
类 sqlalchemy.pool._ConnectionFairy
(sqlalchemy.pool.base.PoolProxiedConnection
)
class sqlalchemy.pool._ConnectionRecord
维护连接池中引用池化连接的位置。
这是Pool
实现内部使用的对象,用于为该Pool
维护的 DBAPI 连接提供上下文管理。该类的公共接口由ConnectionPoolEntry
类描述。请参阅该类以获取公共 API 详细信息。
另请参阅
ConnectionPoolEntry
PoolProxiedConnection
类签名
类 sqlalchemy.pool._ConnectionRecord
(sqlalchemy.pool.base.ConnectionPoolEntry
)