SQLAlchemy 2.0 文档
SQLAlchemy Core
- SQL 语句和表达式 API
- 架构定义语言
- SQL 数据类型对象
- 引擎和连接使用
- 引擎配置
- 使用引擎和连接
- 连接池¶
- 连接池配置
- 切换池实现
- 使用自定义连接函数
- 构建池
- 返回时重置
- 池事件
- 处理断开连接
- 使用 FIFO 与 LIFO
- 在多进程或 os.fork() 中使用连接池
- 直接使用池实例
- API 文档 - 可用池实现
Pool
QueuePool
AsyncAdaptedQueuePool
SingletonThreadPool
AssertionPool
NullPool
StaticPool
ManagesConnection
ConnectionPoolEntry
PoolProxiedConnection
PoolProxiedConnection.close()
PoolProxiedConnection.dbapi_connection
PoolProxiedConnection.detach()
PoolProxiedConnection.driver_connection
PoolProxiedConnection.info
PoolProxiedConnection.invalidate()
PoolProxiedConnection.is_detached
PoolProxiedConnection.is_valid
PoolProxiedConnection.record_info
_ConnectionFairy
_ConnectionRecord
- 核心事件
- 核心 API 基础
项目版本
- 上一章: 使用引擎和连接
- 下一章: 核心事件
- 上一级: 首页
- 本页内容
- 连接池
- 连接池配置
- 切换池实现
- 使用自定义连接函数
- 构建池
- 返回时重置
- 池事件
- 处理断开连接
- 使用 FIFO 与 LIFO
- 在多进程或 os.fork() 中使用连接池
- 直接使用池实例
- API 文档 - 可用池实现
Pool
QueuePool
AsyncAdaptedQueuePool
SingletonThreadPool
AssertionPool
NullPool
StaticPool
ManagesConnection
ConnectionPoolEntry
PoolProxiedConnection
PoolProxiedConnection.close()
PoolProxiedConnection.dbapi_connection
PoolProxiedConnection.detach()
PoolProxiedConnection.driver_connection
PoolProxiedConnection.info
PoolProxiedConnection.invalidate()
PoolProxiedConnection.is_detached
PoolProxiedConnection.is_valid
PoolProxiedConnection.record_info
_ConnectionFairy
_ConnectionRecord
连接池¶
连接池是一种标准技术,用于在内存中维护长期运行的连接以实现高效的重复使用,以及管理应用程序可能同时使用的连接总数。
特别是对于服务器端 Web 应用程序,连接池是维护内存中“池”的活动数据库连接的标准方式,这些连接在请求之间重复使用。
SQLAlchemy 包含几种连接池实现,它们与 Engine
集成。它们也可以直接用于希望将池添加到纯 DBAPI 方法的应用程序。
连接池配置¶
由 create_engine()
函数返回的 Engine
在大多数情况下都集成了一个 QueuePool
,并使用合理的池默认值进行预配置。如果您只是阅读本节以了解如何启用池 - 恭喜!您已经完成了。
最常见的 QueuePool
调优参数可以直接作为关键字参数传递给 create_engine()
:pool_size
、max_overflow
、pool_recycle
和 pool_timeout
。例如
engine = create_engine(
"postgresql+psycopg2://me@localhost/mydb", pool_size=20, max_overflow=0
)
所有 SQLAlchemy 池实现都有一个共同点,即它们都不“预创建”连接 - 所有实现都在第一次使用之前等待创建连接。此时,如果没有额外的并发签出请求来获取更多连接,就不会创建额外的连接。这就是为什么 create_engine()
默认使用大小为 5 的 QueuePool
,而不管应用程序是否真正需要 5 个连接排队 - 池只会增长到该大小,前提是应用程序实际并发使用 5 个连接,在这种情况下,使用一个小池完全是一个合适的默认行为。
注意
QueuePool
类**与 asyncio 不兼容**。当使用 create_async_engine
创建 AsyncEngine
实例时,将使用 AsyncAdaptedQueuePool
类,该类使用与 asyncio 兼容的队列实现。
切换池实现¶
在 create_engine()
中使用不同类型的池的通常方法是使用 poolclass
参数。此参数接受从 sqlalchemy.pool
模块导入的类,并处理为您构建池的细节。这里的一个常见用例是当要禁用连接池时,这可以通过使用 NullPool
实现来实现
from sqlalchemy.pool import NullPool
engine = create_engine(
"postgresql+psycopg2://scott:tiger@localhost/test", poolclass=NullPool
)
使用自定义连接函数¶
有关各种连接自定义例程的概述,请参见 自定义 DBAPI connect() 参数 / 连接时例程 一节。
构建池¶
要单独使用 Pool
,creator
函数是唯一必需的参数,它被首先传递,然后是任何其他选项
import sqlalchemy.pool as pool
import psycopg2
def getconn():
c = psycopg2.connect(user="ed", host="127.0.0.1", dbname="test")
return c
mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)
然后可以使用 Pool.connect()
函数从池中获取 DBAPI 连接。此方法的返回值是一个包含在透明代理中的 DBAPI 连接
# get a connection
conn = mypool.connect()
# use it
cursor_obj = conn.cursor()
cursor_obj.execute("select foo")
透明代理的目的是拦截 close()
调用,这样 DBAPI 连接不会被关闭,而是被返回到池中
# "close" the connection. Returns
# it to the pool.
conn.close()
当代理被垃圾回收时,它也会将包含的 DBAPI 连接返回到池中,尽管 Python 不确定这是否会立即发生(尽管在 cPython 中通常是如此)。但是,不建议使用此用法,特别是与 asyncio DBAPI 驱动程序不兼容。
返回时重置¶
池包括“返回时重置”行为,当连接返回到池时,该行为将调用 DBAPI 连接的 rollback()
方法。这样可以从连接中删除任何现有的事务状态,这不仅包括未提交的数据,还包括表和行锁。对于大多数 DBAPI,调用 rollback()
并不昂贵,如果 DBAPI 已经完成了一个事务,该方法应该是一个无操作。
为非事务性连接禁用返回时重置¶
对于一些非常特殊的用例,使用 rollback()
不起作用,例如,当使用配置为 autocommit 的连接时,或者使用没有 ACID 功能的数据库时,例如 MySQL 的 MyISAM 引擎,则可以禁用返回时重置的行为,这通常出于性能原因。这可以通过使用 Pool.reset_on_return
参数(它也可以通过 Pool
获取,也可以通过 create_engine()
获取,参数名为 create_engine.pool_reset_on_return
)并传递值 None
来实现。下面的例子演示了这一点,同时使用了 create_engine.isolation_level
参数设置 AUTOCOMMIT
non_acid_engine = create_engine(
"mysql://scott:tiger@host/db",
pool_reset_on_return=None,
isolation_level="AUTOCOMMIT",
)
上面的引擎实际上不会在连接返回到连接池时执行 ROLLBACK;由于启用了 AUTOCOMMIT,驱动程序也不会执行任何 BEGIN 操作。
自定义返回时重置方案¶
由单个 rollback()
组成的一般“返回时重置”可能不足以满足某些用例;特别是,使用临时表的应用程序可能希望这些表在连接签入时自动删除。一些(但并非所有)后端包含在数据库连接范围内可以“重置”这些表的功能,这对于连接池重置可能是理想的行为。其他服务器资源(例如准备好的语句句柄和服务器端语句缓存)可能在签入过程中持续存在,这可能是理想的,也可能是不理想的,具体取决于具体情况。同样,一些(但同样不是所有)后端可能提供了一种重置此状态的方法。已知具有此类重置方案的两个 SQLAlchemy 包含的方言包括 Microsoft SQL Server,其中一个未记录但在广泛使用且众所周知的存储过程称为 sp_reset_connection
通常被使用,以及 PostgreSQL,它有一系列经过充分记录的命令,包括 DISCARD
RESET
, DEALLOCATE
和 UNLISTEN
。
以下示例说明了如何使用 Microsoft SQL Server sp_reset_connection
存储过程,并通过 PoolEvents.reset()
事件钩子来替换返回时重置。将 create_engine.pool_reset_on_return
参数设置为 None
,以便自定义方案完全替换默认行为。自定义钩子实现无论如何都会调用 .rollback()
,因为 DBAPI 对提交/回滚的跟踪通常需要与事务状态保持一致
from sqlalchemy import create_engine
from sqlalchemy import event
mssql_engine = create_engine(
"mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
# disable default reset-on-return scheme
pool_reset_on_return=None,
)
@event.listens_for(mssql_engine, "reset")
def _reset_mssql(dbapi_connection, connection_record, reset_state):
if not reset_state.terminate_only:
dbapi_connection.execute("{call sys.sp_reset_connection}")
# so that the DBAPI itself knows that the connection has been
# reset
dbapi_connection.rollback()
Changed in version 2.0.0b3: 向 PoolEvents.reset()
事件添加了附加状态参数,并确保该事件针对所有“重置”事件调用,因此它适合作为自定义“重置”处理程序的位置。以前使用 PoolEvents.checkin()
处理程序的方案仍然可以使用。
另请参阅
连接池的临时表/资源重置 - 在 Microsoft SQL Server 文档中
连接池的临时表/资源重置 在 PostgreSQL 文档中
记录返回时重置事件¶
包括返回时重置在内的连接池事件的日志记录可以设置为 logging.DEBUG
日志级别,以及 sqlalchemy.pool
记录器,或者通过使用 create_engine()
时将 create_engine.echo_pool
设置为 "debug"
来设置
>>> from sqlalchemy import create_engine
>>> engine = create_engine("postgresql://scott:tiger@localhost/test", echo_pool="debug")
上面的连接池将显示详细的日志记录,包括返回时重置
>>> c1 = engine.connect()
DEBUG sqlalchemy.pool.impl.QueuePool Created new connection <connection object ...>
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> checked out from pool
>>> c1.close()
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> being returned to pool
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> rollback-on-return
连接池事件¶
连接池支持一个事件接口,允许在第一次连接时,每次新连接时,以及连接签出和签入时执行钩子。有关详细信息,请参见 PoolEvents
。
处理断开连接¶
连接池能够刷新单个连接,以及其所有连接集,并将以前池化的连接设置为“无效”。一个常见的用例是允许连接池在数据库服务器重新启动后优雅地恢复,并且所有以前建立的连接都不可用。有两种方法可以实现这一点。
断开连接处理 - 悲观¶
悲观方法是指在每次连接池签出开始时在 SQL 连接上发出测试语句,以测试数据库连接是否仍然有效。该实现是方言特定的,并使用 DBAPI 特定的 ping 方法,或通过使用简单的 SQL 语句(如“SELECT 1”)来测试连接的活动状态。
该方法在连接签出过程中增加了少量开销,但除此之外,它是完全消除由于池化连接过时而导致的数据库错误的最简单且可靠的方法。调用应用程序无需担心组织操作,以便能够从池中签出的过时连接中恢复。
在签出时对连接进行悲观测试可以通过使用 Pool.pre_ping
参数实现,该参数可以通过 create_engine()
获取,参数名为 create_engine.pool_pre_ping
engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)
“预 ping”功能在每个方言的基础上工作,要么通过调用 DBAPI 特定的“ping”方法,要么在不可用时发出等效于“SELECT 1”的 SQL,捕获任何错误并将错误检测为“断开连接”情况。如果 ping/错误检查确定连接不可用,则该连接将立即回收,并且所有比当前时间更旧的池化连接都将失效,因此下次签出时,它们也会在使用之前回收。
如果“预 ping”运行时数据库仍然不可用,则初始连接将失败,连接失败的错误将正常传播。在不常见的情况下,数据库可用于连接,但无法响应“ping”,则“pre_ping”将在放弃之前尝试最多三次,传播最后收到的数据库错误。
务必注意,预 ping 方法 **不适用于事务或其他 SQL 操作中间断开的连接**。如果数据库在事务进行中变得不可用,则事务将丢失,并将引发数据库错误。虽然 Connection
对象将检测到“断开连接”情况,并回收连接以及使连接池中的其他连接失效,但引发异常的单个操作将丢失,应用程序需要放弃操作,或者重试整个事务。如果引擎使用 DBAPI 级别的自动提交连接配置,如 设置事务隔离级别,包括 DBAPI 自动提交 中所述,则可以使用事件在操作中间透明地重新连接连接。有关示例,请参见部分 如何“重试”语句执行?。
对于使用“SELECT 1”并捕获错误以检测断开连接的方言,可以使用 DialectEvents.handle_error()
钩子为新的后端特定错误消息增强断开连接测试。
自定义/旧版悲观 ping¶
在添加 create_engine.pool_pre_ping
之前,历史上“预 ping”方法是使用 ConnectionEvents.engine_connect()
引擎事件手动执行的。以下是最常见的方案,用于参考目的,以防应用程序已在使用此类方案或需要特殊行为
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy import select
some_engine = create_engine(...)
@event.listens_for(some_engine, "engine_connect")
def ping_connection(connection, branch):
if branch:
# this parameter is always False as of SQLAlchemy 2.0,
# but is still accepted by the event hook. In 1.x versions
# of SQLAlchemy, "branched" connections should be skipped.
return
try:
# run a SELECT 1. use a core select() so that
# the SELECT of a scalar value without a table is
# appropriately formatted for the backend
connection.scalar(select(1))
except exc.DBAPIError as err:
# catch SQLAlchemy's DBAPIError, which is a wrapper
# for the DBAPI's exception. It includes a .connection_invalidated
# attribute which specifies if this connection is a "disconnect"
# condition, which is based on inspection of the original exception
# by the dialect in use.
if err.connection_invalidated:
# run the same SELECT again - the connection will re-validate
# itself and establish a new connection. The disconnect detection
# here also causes the whole connection pool to be invalidated
# so that all stale connections are discarded.
connection.scalar(select(1))
else:
raise
上述方案的优点在于,我们利用了 SQLAlchemy 的功能来检测已知指示“断开连接”情况的那些 DBAPI 异常,以及 Engine
对象在发生此情况时正确使当前连接池失效,并允许当前 Connection
重新验证到新的 DBAPI 连接上的能力。
断开连接处理 - 乐观¶
当没有使用悲观处理,以及当数据库在连接在事务中使用期间的中途关闭和/或重启时,处理陈旧/关闭连接的另一种方法是让 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
是否正在使用。
关于失效的更多信息¶
Pool
提供“连接失效”服务,这些服务允许显式失效连接,以及自动失效响应于确定导致连接不可用的条件。
“失效”意味着特定 DBAPI 连接将从池中删除并丢弃。 如果不清楚连接本身可能不会关闭,则会对该连接调用 .close()
方法,但是如果此方法失败,则会记录异常,但操作仍会继续。
当使用 Engine
时, Connection.invalidate()
方法是显式失效的常用入口点。 DBAPI 连接可能失效的其他条件包括
DBAPI 异常,例如
OperationalError
,在调用类似connection.execute()
的方法时引发,被检测为指示所谓的“断开连接”条件。 由于 Python DBAPI 没有提供用于确定异常性质的标准系统,因此所有 SQLAlchemy 方言都包含一个名为is_disconnect()
的系统,该系统将检查异常对象的內容,包括字符串消息和任何可能包含在其中的错误代码,以确定此异常是否表示连接不再可用。 如果是这种情况,则会调用_ConnectionFairy.invalidate()
方法,然后丢弃 DBAPI 连接。当连接返回到池时,以及调用
connection.rollback()
或connection.commit()
方法(由池的“返回时重置”行为决定)时,引发异常。 将对连接进行最后一次调用.close()
的尝试,然后将其丢弃。当实现
PoolEvents.checkout()
的侦听器引发DisconnectionError
异常时,表示连接不可用,需要进行新的连接尝试。
所有发生的失效都会调用 PoolEvents.invalidate()
事件。
支持新的数据库错误代码以处理断开连接场景¶
SQLAlchemy 方言都包含一个名为 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 错误调用,包括那些在使用 池预 ping 功能时捕获的错误,用于依赖于断开连接错误处理的后端(2.0 中新增)。
使用 FIFO 与 LIFO¶
QueuePool
类包含一个名为 QueuePool.use_lifo
的标志,也可以从 create_engine()
通过标志 create_engine.pool_use_lifo
访问它。 将此标志设置为 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
调用Engine.dispose()
,并将Engine.dispose.close
参数的值设置为False
。这样,新的进程就不会触碰任何父进程的连接,而是会从新的连接开始。这是推荐的方法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 文档 - 可用的池实现¶
对象名称 | 描述 |
---|---|
代理一个 DBAPI 连接,并提供对引用进行返回的支持。 |
|
维护连接池中的一个位置,该位置引用一个池化连接。 |
|
一个 |
|
一个与 asyncio 兼容的 |
|
用于维护代表 |
|
两个连接管理接口 |
|
一个不池化连接的池。 |
|
连接池的抽象基类。 |
|
一个 |
|
一个为每个线程维护一个连接的池。 |
|
一个只包含一个连接的池,用于所有请求。 |
- class sqlalchemy.pool.Pool¶
连接池的抽象基类。
类签名
class
sqlalchemy.pool.Pool
(sqlalchemy.log.Identified
,sqlalchemy.event.registry.EventTarget
)-
method
sqlalchemy.pool.Pool.
__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¶ –
如果为 True,则连接池将记录信息输出,例如连接何时失效以及何时将连接回收至默认的日志处理程序,默认情况下该处理程序为
sys.stdout
,用于输出。如果设置为字符串"debug"
,则日志记录将包含池检出和检入。可以通过使用
create_engine.echo_pool
参数,在create_engine()
调用中设置Pool.echo
参数。另请参阅
配置日志记录 - 关于如何配置日志记录的更多详细信息。
reset_on_return¶ –
确定在连接返回到池时对其采取的步骤,这些步骤没有被
Connection
处理。可以通过使用create_engine.pool_reset_on_return
参数,从create_engine()
中获得。Pool.reset_on_return
可以具有以下任何值"rollback"
- 对连接调用 rollback(),以释放锁和事务资源。这是默认值。绝大多数用例应该保持此值设置。"commit"
- 对连接调用 commit(),以释放锁和事务资源。如果数据库在发出提交时缓存查询计划(例如 Microsoft SQL Server),则此处的提交可能是有利的。但是,此值比“rollback”更危险,因为事务中存在的任何数据更改都会无条件地提交。None
- 不要对连接做任何操作。如果数据库/DBAPI 始终以纯“自动提交”模式工作,或者如果使用PoolEvents.reset()
事件处理程序建立了自定义重置处理程序,则此设置可能适用。True
- 与“rollback”相同,这是为了向后兼容。False
- 与 None 相同,这是为了向后兼容。
为了进一步自定义重置返回,可以使用
PoolEvents.reset()
事件挂钩,它可以在重置时执行任何所需的连接活动。events¶ – 一个包含 2 元组的列表,每个元组的形式为
(callable, target)
,这些元组将在构建时传递给listen()
。提供此参数是为了使事件侦听器可以在应用方言级别侦听器之前通过create_engine()
分配。dialect¶ – 一个
Dialect
,它将负责在 DBAPI 连接上调用 rollback()、close() 或 commit()。如果省略,则使用内置的“存根”方言。使用create_engine()
的应用程序不应使用此参数,因为它是通过引擎创建策略处理的。pre_ping¶ –
如果为 True,则池将在检出时在连接上发出“ping”(通常是“SELECT 1”,但特定于方言),以测试连接是否还活着。如果不是,则连接将被透明地重新连接,并且在成功之后,在该时间戳之前建立的所有其他池连接都会失效。要求也传递一个方言来解释断开连接错误。
1.2 版中的新增功能。
-
method
sqlalchemy.pool.Pool.
connect() → PoolProxiedConnection¶ 从连接池中返回一个 DBAPI 连接。
该连接经过了增强,当调用其
close()
方法时,连接将被返回到连接池。
-
method
sqlalchemy.pool.Pool.
dispose() → None¶ 释放连接池。
此方法允许已签出的连接保持打开状态,因为它只影响连接池中的空闲连接。
另请参阅
-
method
- class sqlalchemy.pool.QueuePool¶
一个
Pool
,它对打开的连接数量设置限制。QueuePool
是所有Engine
对象的默认连接池实现,除了使用:memory:
数据库的 SQLite。QueuePool
类**与 asyncio 和create_async_engine()
不兼容**。当使用create_async_engine()
且未指定其他类型的连接池时,AsyncAdaptedQueuePool
类会被自动使用。类签名
-
method
sqlalchemy.pool.QueuePool.
__init__(creator: _CreatorFnType | _CreatorWRecFnType, pool_size: int = 5, max_overflow: int = 10, timeout: float = 30.0, use_lifo: bool = False, **kw: Any)¶ 构造一个 QueuePool。
- 参数:
creator¶ – 一个可调用的函数,返回一个 DB-API 连接对象,与
Pool.creator
中的相同。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,服务器端超时方案可以减少在使用量非高峰期使用的连接数量。在规划服务器端超时时,请确保使用回收或预 ping 策略来优雅地处理过时的连接。
版本 1.3 中新增。
**kw¶ – 其他关键字参数,包括
Pool.recycle
,Pool.echo
,Pool.reset_on_return
等,将传递给Pool
构造函数。
-
method
sqlalchemy.pool.QueuePool.
dispose() → None¶ 释放连接池。
此方法允许已签出的连接保持打开状态,因为它只影响连接池中的空闲连接。
另请参阅
-
method
- class sqlalchemy.pool.AsyncAdaptedQueuePool¶
一个与 asyncio 兼容的
QueuePool
版本。此池默认情况下在使用从
AsyncEngine
生成的create_async_engine()
引擎时使用。它使用一个与 asyncio 兼容的队列实现,该实现不使用threading.Lock
。AsyncAdaptedQueuePool
的参数和操作与QueuePool
相同。
- class sqlalchemy.pool.SingletonThreadPool¶
一个为每个线程维护一个连接的池。
为每个线程维护一个连接,绝不会将连接移至创建它的线程以外的线程。
警告
SingletonThreadPool
会对超出pool_size
设置大小的任意连接调用.close()
,例如,如果使用的唯一 **线程标识** 超过了pool_size
的值。这种清理是非确定性的,并且不敏感于与这些线程标识相关的连接当前是否正在使用。SingletonThreadPool
可能会在将来的版本中得到改进,但是在其当前状态下,它通常只用于使用 SQLite:memory:
数据库的测试场景,不建议用于生产环境。SingletonThreadPool
类 **与 asyncio 和create_async_engine()
不兼容**。选项与
Pool
的选项相同,以及- 参数:
pool_size¶ – 要一次维护连接的线程数。默认为 5。
当使用基于内存的数据库时,SQLite 方言会自动使用
SingletonThreadPool
。见 SQLite。成员
-
method
sqlalchemy.pool.SingletonThreadPool.
connect() → PoolProxiedConnection¶ 从连接池中返回一个 DBAPI 连接。
该连接经过了增强,当调用其
close()
方法时,连接将被返回到连接池。
-
method
sqlalchemy.pool.SingletonThreadPool.
dispose() → None¶ 释放连接池。
-
method
sqlalchemy.pool.SingletonThreadPool.
recreate() → SingletonThreadPool¶ 返回一个新的
Pool
,其类型与当前连接池相同,并使用相同的创建参数进行配置。
- class sqlalchemy.pool.AssertionPool¶
一个
Pool
,它允许在任何给定时间最多只有一个签出的连接。如果一次检出多个连接,则会引发异常。这对于调试使用比预期更多的连接的代码很有用。
AssertionPool
类 **与 asyncio 和create_async_engine()
兼容**。成员
-
method
sqlalchemy.pool.AssertionPool.
dispose() → None¶ 释放连接池。
此方法允许已签出的连接保持打开状态,因为它只影响连接池中的空闲连接。
另请参阅
-
method
sqlalchemy.pool.AssertionPool.
recreate() → AssertionPool¶ 返回一个新的
Pool
,其类型与当前连接池相同,并使用相同的创建参数进行配置。
-
method
- class sqlalchemy.pool.NullPool¶
一个不池化连接的池。
相反,它实际上为每个连接打开/关闭操作打开和关闭底层 DB-API 连接。
此池实现不支持重新连接相关的函数,例如
recycle
和连接失效,因为没有持久地保存连接。NullPool
类 **与 asyncio 和create_async_engine()
兼容**。成员
类签名
-
method
sqlalchemy.pool.NullPool.
dispose() → None¶ 释放连接池。
此方法允许已签出的连接保持打开状态,因为它只影响连接池中的空闲连接。
另请参阅
-
method
- class sqlalchemy.pool.StaticPool¶
一个只包含一个连接的池,用于所有请求。
目前仅部分支持与重连相关的功能,例如
recycle
和连接失效(也用于支持自动重连),并且可能不会产生良好的结果。The
StaticPool
类 **与** asyncio 和create_async_engine()
**兼容**。成员
类签名
class
sqlalchemy.pool.StaticPool
(sqlalchemy.pool.base.Pool
)-
method
sqlalchemy.pool.StaticPool.
dispose() → None¶ 释放连接池。
此方法允许已签出的连接保持打开状态,因为它只影响连接池中的空闲连接。
另请参阅
-
method
sqlalchemy.pool.StaticPool.
recreate() → StaticPool¶ 返回一个新的
Pool
,其类型与当前连接池相同,并使用相同的创建参数进行配置。
-
method
- class sqlalchemy.pool.ManagesConnection¶
两个连接管理接口
PoolProxiedConnection
和ConnectionPoolEntry
的共同基础。这两个对象通常通过连接池事件钩子在面向公众的 API 中公开,文档见
PoolEvents
。2.0 版新增。
-
attribute
sqlalchemy.pool.ManagesConnection.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容的对象,对于传统的同步风格方言,它由正在使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是由 SQLAlchemy 方言本身提供的适配器对象;可以通过
ManagesConnection.driver_connection
属性访问底层的 asyncio 对象。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
attribute
sqlalchemy.pool.ManagesConnection.
driver_connection: Any | None¶ 由 Python DBAPI 或数据库驱动程序使用的“驱动程序级”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它将没有标准的 pep-249 方法。1.4.24 版新增。
-
attribute
sqlalchemy.pool.ManagesConnection.
info¶ 与底层 DBAPI 连接(由此
ManagesConnection
实例引用)关联的信息字典,允许将用户定义的数据与连接关联。此字典中的数据对于 DBAPI 连接本身的整个生命周期都是持久的,包括在池检入和检出期间。当连接失效并被新连接替换时,此字典将被清除。
对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如如果它被分离,该属性将返回一个属于该ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
method
sqlalchemy.pool.ManagesConnection.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 将托管连接标记为已失效。
另请参阅
-
attribute
sqlalchemy.pool.ManagesConnection.
record_info¶ 与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,此字典将在连接池中特定条目的重连和连接失效期间持续存在。对于没有与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如被分离的实例,该属性将返回 None。与ManagesConnection.info
字典不同,该字典永远不会是 None。
-
attribute
- class sqlalchemy.pool.ConnectionPoolEntry¶
用于维护代表
Pool
实例的单个数据库连接的对象的接口。ConnectionPoolEntry
对象代表连接池中特定连接的长期维护,包括使该连接过期或失效以将其替换为新的连接,而新的连接将继续由同一个ConnectionPoolEntry
实例维护。与PoolProxiedConnection
相比,PoolProxiedConnection
是短期、每次签出时的连接管理器,而此对象在连接池中特定“槽”的整个生命周期内持续存在。ConnectionPoolEntry
对象主要在它被传递到连接池事件钩子时对面向公众的 API 代码可见,例如PoolEvents.connect()
和PoolEvents.checkout()
。版本 2.0 中新增:
ConnectionPoolEntry
为内部_ConnectionRecord
类提供面向公众的接口。-
method
sqlalchemy.pool.ConnectionPoolEntry.
close() → None¶ 关闭此连接池条目管理的 DBAPI 连接。
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容的对象,对于传统的同步风格方言,它由使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是由 SQLAlchemy 方言本身提供的适配器对象;底层 asyncio 对象可以通过
ManagesConnection.driver_connection
属性获得。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
driver_connection: Any | None¶ 由 Python DBAPI 或数据库驱动程序使用的“驱动程序级”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。对于 asyncio 数据库驱动程序,它将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它将没有标准的 pep-249 方法。1.4.24 版新增。
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
in_use¶ 如果连接当前处于签出状态,则返回 True。
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
info¶ 继承自
ManagesConnection.info
属性 ofManagesConnection
与底层 DBAPI 连接(由此
ManagesConnection
实例引用)关联的信息字典,允许将用户定义的数据与连接关联。此字典中的数据对于 DBAPI 连接本身的整个生命周期都是持久的,包括在池检入和检出期间。当连接失效并被新连接替换时,此字典将被清除。
对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如如果它被分离,该属性将返回一个属于该ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
method
sqlalchemy.pool.ConnectionPoolEntry.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 继承自
ManagesConnection.invalidate()
方法 ofManagesConnection
将托管连接标记为已失效。
另请参阅
-
attribute
sqlalchemy.pool.ConnectionPoolEntry.
record_info¶ 继承自
ManagesConnection.record_info
属性 ofManagesConnection
与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,此字典将在连接池中特定条目的重连和连接失效期间持续存在。对于没有与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如被分离的实例,该属性将返回 None。与ManagesConnection.info
字典不同,该字典永远不会是 None。
-
method
- 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.
close() → None¶ 将此连接释放回连接池。
该
PoolProxiedConnection.close()
方法覆盖了 PEP 249.close()
方法,修改了其行为,改为将代理连接 释放 回连接池。释放回连接池后,连接是否保持“打开”状态并保留在 Python 进程中,还是真正关闭并从 Python 进程中移除,取决于使用的连接池实现及其配置和当前状态。
-
属性
sqlalchemy.pool.PoolProxiedConnection.
dbapi_connection: DBAPIConnection | None¶ 对正在跟踪的实际 DBAPI 连接的引用。
这是一个 PEP 249 兼容的对象,对于传统的同步风格方言,由使用的第三方 DBAPI 实现提供。对于 asyncio 方言,实现通常是 SQLAlchemy 方言本身提供的适配器对象;底层 asyncio 对象可通过
ManagesConnection.driver_connection
属性访问。SQLAlchemy 的 DBAPI 连接接口基于
DBAPIConnection
协议对象
-
方法
sqlalchemy.pool.PoolProxiedConnection.
detach() → None¶ 将此连接与连接池分离。
这意味着连接在关闭时不再返回连接池,而是被完全关闭。关联的
ConnectionPoolEntry
与此 DBAPI 连接分离。请注意,分离后,连接池实现强加的任何整体连接限制约束都可能被违反,因为分离的连接已从连接池的知识和控制中移除。
-
属性
sqlalchemy.pool.PoolProxiedConnection.
driver_connection: Any | None¶ 由 Python DBAPI 或数据库驱动程序使用的“驱动程序级”连接对象。
对于传统的 PEP 249 DBAPI 实现,此对象将与
ManagesConnection.dbapi_connection
的对象相同。对于 asyncio 数据库驱动程序,这将是该驱动程序使用的最终“连接”对象,例如asyncpg.Connection
对象,它将没有标准的 pep-249 方法。1.4.24 版新增。
-
属性
sqlalchemy.pool.PoolProxiedConnection.
info¶ 继承自
ManagesConnection.info
属性 ofManagesConnection
与底层 DBAPI 连接(由此
ManagesConnection
实例引用)关联的信息字典,允许将用户定义的数据与连接关联。此字典中的数据对于 DBAPI 连接本身的整个生命周期都是持久的,包括在池检入和检出期间。当连接失效并被新连接替换时,此字典将被清除。
对于一个未与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如如果它被分离,该属性将返回一个属于该ConnectionPoolEntry
的字典。因此,ManagesConnection.info
属性将始终提供一个 Python 字典。
-
方法
sqlalchemy.pool.PoolProxiedConnection.
invalidate(e: BaseException | None = None, soft: bool = False) → None¶ 继承自
ManagesConnection.invalidate()
方法 ofManagesConnection
将托管连接标记为已失效。
另请参阅
-
属性
sqlalchemy.pool.PoolProxiedConnection.
is_detached¶ 如果此
PoolProxiedConnection
与连接池分离,则返回 True。
-
属性
sqlalchemy.pool.PoolProxiedConnection.
is_valid¶ 如果此
PoolProxiedConnection
仍然引用一个活动的 DBAPI 连接,则返回 True。
-
属性
sqlalchemy.pool.PoolProxiedConnection.
record_info¶ 继承自
ManagesConnection.record_info
属性 ofManagesConnection
与此
ManagesConnection
关联的持久信息字典。与
ManagesConnection.info
字典不同,此字典的生命周期是拥有它的ConnectionPoolEntry
的生命周期;因此,此字典将在连接池中特定条目的重连和连接失效期间持续存在。对于没有与
ConnectionPoolEntry
关联的PoolProxiedConnection
实例,例如被分离的实例,该属性将返回 None。与ManagesConnection.info
字典不同,该字典永远不会是 None。
-
方法
- 类 sqlalchemy.pool._ConnectionFairy¶
代理一个 DBAPI 连接,并提供对引用进行返回的支持。
这是
Pool
实现使用的内部对象,用于为该Pool
提供的 DBAPI 连接提供上下文管理。此类的公共面向接口由PoolProxiedConnection
类描述。有关公共 API 详细信息,请参阅该类。名称“fairy”的灵感来自
_ConnectionFairy
对象的生命周期是短暂的,因为它只在从连接池检出的特定 DBAPI 连接的持续时间内存在,并且作为透明代理,它大多是不可见的。类签名
类
sqlalchemy.pool._ConnectionFairy
(sqlalchemy.pool.base.PoolProxiedConnection
)
- 类 sqlalchemy.pool._ConnectionRecord¶
维护连接池中的一个位置,该位置引用一个池化连接。
这是
Pool
实现使用的内部对象,用于为该Pool
提供的 DBAPI 连接提供上下文管理。此类的公共面向接口由ConnectionPoolEntry
类描述。有关公共 API 详细信息,请参阅该类。类签名
类
sqlalchemy.pool._ConnectionRecord
(sqlalchemy.pool.base.ConnectionPoolEntry
)
flambé! 龙和 炼金术士 图片设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。文档最后生成时间:2024 年 11 月 8 日星期五上午 8:41:19 EST