版本:1.1.0b2 |发布日期:2016年7月1日

SQLAlchemy 1.1文档

连接池

连接池是一种标准技术,用于维护内存中长时间运行的连接,以便高效地重用,并提供对应用程序可能同时使用的连接总数的管理。

特别是对于服务器端Web应用程序,连接池是在内存中维护活动数据库连接“池”的标准方法,这些连接在请求之间重用。

SQLAlchemy包含几个与Engine集成的连接池实现。它们也可以直接用于想要将池化添加到其他普通DBAPI方法的应用程序。

连接池配置

The Engine returned by the create_engine() function in most cases has a QueuePool integrated, pre-configured with reasonable pooling defaults. 如果您只是阅读本节以了解如何启用共享池 - 恭喜!你已经完成了。

The most common QueuePool tuning parameters can be passed directly to create_engine() as keyword arguments: pool_size, max_overflow, pool_recycle and pool_timeout. 例如:

engine = create_engine('postgresql://me@localhost/mydb',
                       pool_size=20, max_overflow=0)

在SQLite的情况下,方言选择SingletonThreadPoolNullPool,以提供与SQLite的线程和锁定模型更好的兼容性,并提供合理的默认行为SQLite“内存”数据库,它们将整个数据集保持在单个连接的范围内。

所有的SQLAlchemy池实现都有一个共同点,那就是它们中没有一个是“预创建”连接 - 所有实现都等到创建连接之前首次使用。此时,如果没有更多连接的并发签出请求,则不会创建其他连接。This is why it’s perfectly fine for create_engine() to default to using a QueuePool of size five without regard to whether or not the application really needs five connections queued up - the pool would only grow to that size if the application actually used five connections concurrently, in which case the usage of a small pool is an entirely appropriate default behavior.

切换池实现

The usual way to use a different kind of pool with create_engine() is to use the poolclass argument. 该参数接受从sqlalchemy.pool模块导入的类,并处理为您构建池的详细信息。常见的选项包括用SQLite指定QueuePool

from sqlalchemy.pool import QueuePool
engine = create_engine('sqlite:///file.db', poolclass=QueuePool)

使用NullPool

from sqlalchemy.pool import NullPool
engine = create_engine(
          'postgresql+psycopg2://scott:tiger@localhost/test',
          poolclass=NullPool)

使用自定义连接功能

所有的Pool类接受一个参数creator,它是一个可调用的参数,用于创建一个新的连接。create_engine() accepts this function to pass onto the pool via an argument of the same name:

import sqlalchemy.pool as pool
import psycopg2

def getconn():
    c = psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
    # do things with 'c' to set up
    return c

engine = create_engine('postgresql+psycopg2://', creator=getconn)

对于大多数“初始化连接”例程来说,使用PoolEvents事件钩子更方便,所以create_engine()的通常URL参数仍然可用。creator is there as a last resort for when a DBAPI has some form of connect that is not at all supported by SQLAlchemy.

构建一个池

要单独使用Poolcreator函数是唯一需要的参数,并首先传递,然后是任何其他选项:

import sqlalchemy.pool as pool
import psycopg2

def getconn():
    c = psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
    return c

mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)

DBAPI连接可以使用Pool.connect()函数从池中获取。此方法的返回值是包含在透明代理中的DBAPI连接:

# get a connection
conn = mypool.connect()

# use it
cursor = conn.cursor()
cursor.execute("select foo")

透明代理的目的是拦截close()调用,而不是关闭DBAPI连接,它将返回到池:

# "close" the connection.  Returns
# it to the pool.
conn.close()

当垃圾收集时,代理也会将其包含的DBAPI连接返回到池中,尽管在Python中这不是确定性的,而是立即发生(尽管这是典型的cPython)。

close()步骤还执行调用DBAPI连接的rollback()方法的重要步骤。这样就可以删除连接上的任何现有事务,不仅可以确保在下次使用时不会保留现有状态,还可以释放表和行锁,以及删除任何孤立的数据快照。可以使用Poolreset_on_return选项禁用此行为。

一个特定的预先创建的Pool可以通过将其传递给create_engine()pool参数与一个或多个引擎共享:

e = create_engine('postgresql://', pool=mypool)

池事件

连接池支持一个事件接口,该接口允许在第一次连接时执行钩子,在每个新的连接上执行,并在结帐和签入连接时执行。有关详细信息,请参阅PoolEvents

处理断开连接

连接池可以刷新单个连接以及整个连接,将之前连接的连接设置为“无效”。一个常见的用例是允许连接池在数据库服务器重新启动时正常恢复,并且以前建立的所有连接都不再起作用。有两种方法。

断开处理 - 乐观

最常见的方法是让SQLAlchemy在发生时断开连接,此时池将被刷新。假定PoolEngine结合使用。Engine具有可以检测断开事件并自动刷新池的逻辑。

Connection尝试使用DBAPI连接,并且引发了与“disconnect”事件相对应的异常时,连接将失效。然后,Connection调用Pool.recreate()方法,有效地使所有未被检出的连接失效,以便在下次检出时用新的连接替换掉。

from sqlalchemy import create_engine, exc
e = create_engine(...)
c = e.connect()

try:
    # suppose the database has been restarted.
    c.execute("SELECT * FROM table")
    c.close()
except exc.DBAPIError, 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("SELECT * FROM table")

上面的例子说明不需要特别的干预,在检测到断开事件之后,池正常继续。但是,引发了一个例外。在使用ORM会话的典型Web应用程序中,上述条件将对应于单个请求失败并出现500错误,然后Web应用程序正常继续。因此,这种方法是“乐观的”,因为频繁的数据库重启是不可预料的。

设置池回收

可以增加“乐观”方法的其他设置是设置池回收参数。此参数可防止池使用特定时间的特定连接,并适用于数据库后端(如MySQL),这些后端会自动关闭在特定时间段后过时的连接:

from sqlalchemy import create_engine
e = create_engine("mysql://scott:tiger@localhost/test", pool_recycle=3600)

以上,任何已经打开超过一个小时的DBAPI连接都将失效并在下次结账时被替换。请注意,仅在结帐时发生失效,而不是处于签出状态的任何连接。pool_recycle is a function of the Pool itself, independent of whether or not an Engine is in use.

断开处理 - 悲观

在从池中检出的每个连接发出一些额外的SQL代价的情况下,由checkout事件处理程序建立的“ping”操作可以在使用之前检测到无效的连接。在现代SQLAlchemy中,最好的方法是使用ConnectionEvents.engine_connect()事件,假设使用Engine,而不仅仅是一个原始的Pool

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:
        # "branch" refers to a sub-connection of a connection,
        # we don't want to bother pinging on these.
        return

    # turn off "close with result".  This flag is only used with
    # "connectionless" execution, otherwise will be False in any case
    save_should_close_with_result = connection.should_close_with_result
    connection.should_close_with_result = False

    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
    finally:
        # restore "close with result"
        connection.should_close_with_result = save_should_close_with_result

上述配方的好处是,我们利用SQLAlchemy的工具来检测那些已知指示“断开”情况的DBAPI异常,以及Engine对象正确地使当前连接无效的能力当发生这种情况时,允许当前的Connection重新验证到新的DBAPI连接。

对于不使用EnginePool使用情况的常见情况,可以使用以前的方法,如下所示:

from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool

@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        # raise DisconnectionError - pool will try
        # connecting again up to three times before raising.
        raise exc.DisconnectionError()
    cursor.close()

Above, the Pool object specifically catches DisconnectionError and attempts to create a new DBAPI connection, up to three times, before giving up and then raising InvalidRequestError, failing the connection. 上述方法的缺点是,我们没有任何简单的方法来确定引发的异常事实上是否是“断开”的情况,因为没有EngineDialect

更多关于无效

Pool提供了“连接无效”服务,允许连接的显式失效以及自动失效响应于确定使连接不可用的条件。

“无效”意味着特定的DBAPI连接将从池中删除并丢弃。如果不清楚连接本身可能未关闭,则在此连接上调用.close()方法,但如果此方法失败,则会记录异常,但操作仍在继续。

当使用Engine时,Connection.invalidate()方法是通常显式失效的入口点。DBAPI连接可能失效的其他条件包括:

  • 在调用诸如connection.execute()之类的方法时引发的诸如OperationalError的DBAPI异常被检测为指示所谓的“断开”条件。由于Python DBAPI没有提供用于确定异常性质的标准系统,所有的SQLAlchemy方言都包含一个称为is_disconnect()的系统,它将检查异常对象的内容,包括字符串消息和任何潜在的包含的错误代码,以确定此异常是否表示连接不再可用。如果是这种情况,则调用_ConnectionFairy.invalidate()方法,然后丢弃DBAPI连接。
  • 当连接返回到池时,并根据池的“reset on return”行为调用connection.rollback()connection.commit()方法,抛出异常。在连接上调用.close()的最后一次尝试将被丢弃。
  • 当实现PoolEvents.checkout()的侦听器引发DisconnectionError异常时,表明连接将不可用,并且需要建立新的连接。

所有发生的无效将调用PoolEvents.invalidate()事件。

使用连接池与多处理

在使用连接池时,以及在使用通过create_engine()创建的Engine时扩展至关重要的是,共享连接不会共享到分叉进程 T6>。TCP连接表示为文件描述符,通常跨越进程边界工作,这意味着这将导致代表两个或多个完全独立的Python解释器状态并发访问文件描述符。

有两种方法来处理这个问题。

首先是在子进程内或在现有的Engine内创建一个新的Engine,在子进程之前调用Engine.dispose()进程使用任何连接。这将从池中删除所有现有的连接,以便使所有新的连接。下面是一个使用multiprocessing.Process的简单版本,但是这个想法应该适应使用中的分叉风格:

eng = create_engine("...")

def run_in_process():
  eng.dispose()

  with eng.connect() as conn:
      conn.execute("...")

p = Process(target=run_in_process)

下一个方法是用事件来处理Pool本身,以便连接在子进程中自动失效。这有点神奇,但可能更为万无一失:

from sqlalchemy import event
from sqlalchemy import exc
import os

eng = 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.connection = connection_proxy.connection = None
        raise exc.DisconnectionError(
                "Connection record belongs to pid %s, "
                "attempting to check out in pid %s" %
                (connection_record.info['pid'], pid)
        )

上面,我们使用类似于Disconnect Handling - Pessimistic中描述的方法,将源自不同父进程的DBAPI连接视为“无效”连接,强制池将连接记录回收到建立一个新的连接。

API文档 - 可用的池实现

class sqlalchemy.pool.Pool(creator, recycle=-1, echo=None, use_threadlocal=False, logging_name=None, reset_on_return=True, listeners=None, events=None, _dispatch=None, _dialect=None)

基础:sqlalchemy.log.Identified

连接池的抽象基类。

__init__(creator, recycle=-1, echo=None, use_threadlocal=False, logging_name=None, reset_on_return=True, listeners=None, events=None, _dispatch=None, _dialect=None)

构建一个池。

参数:
  • creator – a callable function that returns a DB-API connection object. 该函数将被调用参数。
  • recycle – If set to non -1, number of seconds between connection recycling, which means upon checkout, if this timeout is surpassed the connection will be closed and replaced with a newly opened connection. 默认为-1。
  • logging_name – String identifier which will be used within the “name” field of logging records generated within the “sqlalchemy.pool” logger. 缺省为对象ID的十六进制字符串。
  • echo – If True, connections being pulled and retrieved from the pool will be logged to the standard output, as well as pool sizing information. 通过为“sqlalchemy.pool”命名空间启用日志记录,也可以实现回声。默认为False。
  • use_threadlocal -

    如果设置为True,则在同一个应用程序线程中重复调用connect()将保证返回相同的连接对象(如果已从池中检索到并且尚未返回)。默认情况下,以单个交易为代价提供轻微的性能优势。提供了Pool.unique_connection()方法来返回一致的唯一连接,以在设置标志时绕过此行为。

    警告

    Pool.use_threadlocal标志不会影响Engine.connect()的行为。Engine.connect() makes use of the Pool.unique_connection() method which does not use thread local context. 要产生引用Pool.connect()方法的Connection,请使用Engine.contextual_connect()

    请注意,其他的SQLAlchemy连接系统如Engine.execute()以及orm Session内部使用Engine.contextual_connect()所以这些函数与Pool.use_threadlocal设置兼容。

    也可以看看

    Using the Threadlocal Execution Strategy - contains detail on the “threadlocal” engine strategy, which provides a more comprehensive approach to “threadlocal” connectivity for the specific use case of using Engine and Connection objects directly.

  • reset_on_return -

    确定连接返回到池时的步骤。reset_on_return可以具有以下任何值:

    • "rollback" - 在连接上调用rollback()来释放锁和事务资源。这是默认值。绝大多数用例都应该保留这个值。
    • True - 与'rollback'相同,这是为了向后兼容。
    • "commit" - 在连接上调用commit(),释放锁和事务资源。如果发出提交(例如Microsoft SQL Server),那么对于缓存查询计划的数据库而言,此处的提交可能是可取的。但是,这个值比“回滚”更危险,因为交易中出现的任何数据变化都是无条件承诺的。
    • None - don’t do anything on the connection. 这个设置只能在没有事务支持的数据库上进行,即MyISAM。没有做任何事情,性能可以提高。This setting should never be selected for a database that supports transactions, as it will lead to deadlocks and stale state.
    • "none" - 与None相同

      版本0.9.10中的新功能

    • False - 与None相同,这是为了向后兼容。

    Changed in version 0.7.6: Pool.reset_on_return accepts "rollback" and "commit" arguments.

  • events – a list of 2-tuples, each of the form (callable, target) which will be passed to event.listen() upon construction. 在这里提供,这样在应用方言级侦听器之前,可以通过create_engine()分配事件侦听器。
  • 听众 - 弃用。DBLAPI连接创建,签出并签入池时接收事件的PoolListener对象或可调用字典的列表。这已被listen()取代。
连接 T0> ( T1> ) T2> ¶ T3>

从池中返回一个DBAPI连接。

连接被调用,以便当它的close()方法被调用时,连接将被返回到池中。

处置 T0> ( T1> ) T2> ¶ T3>

处置这个池。

这种方法使检出连接保持开放的可能性,因为它只影响在池中空闲的连接。

另请参阅Pool.recreate()方法。

重新创建 T0> ( T1> ) T2> ¶ T3>

返回一个新的Pool,与这个相同的类,并配置相同的创建参数。

这个方法和dispose()结合使用来关闭整个Pool,并在它的位置创建一个新的。

unique_connection T0> ( T1> ) T2> ¶ T3>

生成一个没有被任何线程本地上下文引用的DBAPI连接。

Pool.use_threadlocal标志未设置为True时,此方法相当于Pool.connect()Pool.use_threadlocal为True时,Pool.unique_connection()方法提供绕过threadlocal上下文的手段。

class sqlalchemy.pool。 QueuePool creatorpool_size = 5 max_overflow = 10,timeout = 30,** kw / T10>

基础:sqlalchemy.pool.Pool

对打开的连接数量施加限制的Pool

QueuePool is the default pooling implementation used for all Engine objects, unless the SQLite dialect is in use.

__init__(creator, pool_size=5, max_overflow=10, timeout=30, **kw)

构建一个QueuePool。

参数:
  • creator – a callable function that returns a DB-API connection object, same as that of Pool.creator.
  • pool_size – The size of the pool to be maintained, defaults to 5. 这是将永久保存在池中的最大数量的连接。请注意,池开始时没有连接;一旦请求连接数量,连接数量将保持不变。pool_size can be set to 0 to indicate no size limit; to disable pooling, use a NullPool instead.
  • max_overflow - 池的最大溢出大小。当检出连接的数量达到pool_size中设置的大小时,将返回其他连接,直至达到此限制。当这些附加连接返回到池时,它们将被断开并丢弃。It follows then that the total number of simultaneous connections the pool will allow is pool_size + max_overflow, and the total number of “sleeping” connections the pool will allow is pool_size. max_overflow can be set to -1 to indicate no overflow limit; no limit will be placed on the total number of concurrent connections. 默认为10。
  • timeout – The number of seconds to wait before giving up on returning a connection. 默认为30。
  • **kw – Other keyword arguments including Pool.recycle, Pool.echo, Pool.reset_on_return and others are passed to the Pool constructor.
连接 T0> ( T1> ) T2> ¶ T3>
inherited from the connect() method of Pool

从池中返回一个DBAPI连接。

连接被调用,以便当它的close()方法被调用时,连接将被返回到池中。

unique_connection T0> ( T1> ) T2> ¶ T3>
inherited from the unique_connection() method of Pool

生成一个没有被任何线程本地上下文引用的DBAPI连接。

Pool.use_threadlocal标志未设置为True时,此方法相当于Pool.connect()Pool.use_threadlocal为True时,Pool.unique_connection()方法提供绕过threadlocal上下文的手段。

class sqlalchemy.pool。 SingletonThreadPool creatorpool_size = 5 ** kw

基础:sqlalchemy.pool.Pool

每个线程维护一个连接的池。

每个线程保持一个连接,不要将连接移动到除创建它之外的线程。

警告

the SingletonThreadPool will call .close() on arbitrary connections that exist beyond the size setting of pool_size, e.g. if more unique thread identities than what pool_size states are used. 这种清理是非确定性的,对链接到这些线程标识的连接是否正在使用不敏感。

SingletonThreadPool may be improved in a future release, however in its current status it is generally used only for test scenarios using a SQLite :memory: database and is not recommended for production use.

选项与Pool的选项相同,以及:

参数:pool_size – The number of threads in which to maintain connections at once. 默认为五。

SingletonThreadPool is used by the SQLite dialect automatically when a memory-based database is used. 请参阅SQLite

__init__(creator, pool_size=5, **kw)
class sqlalchemy.pool.AssertionPool(*args, **kw)

基础:sqlalchemy.pool.Pool

一个Pool允许在任何给定的时间最多检出一个连接。

如果同时检出多个连接,将会引发异常。用于调试使用比所需更多的连接的代码。

Changed in version 0.7: AssertionPool also logs a traceback of where the original connection was checked out, and reports this in the assertion error raised.

class sqlalchemy.pool.NullPool(creator, recycle=-1, echo=None, use_threadlocal=False, logging_name=None, reset_on_return=True, listeners=None, events=None, _dispatch=None, _dialect=None)

基础:sqlalchemy.pool.Pool

没有连接池的池

相反,它打开和关闭每个连接打开/关闭底层DB-API连接。

这个池实现不支持重新连接相关的函数,如recycle和连接失效,因为没有连接持久。

Changed in version 0.7: NullPool is used by the SQlite dialect automatically when a file-based database is used. 请参阅SQLite

class sqlalchemy.pool.StaticPool(creator, recycle=-1, echo=None, use_threadlocal=False, logging_name=None, reset_on_return=True, listeners=None, events=None, _dispatch=None, _dialect=None)

基础:sqlalchemy.pool.Pool

只有一个连接的池,用于所有请求。

这个Pool实现当前不支持重新连接相关的函数,如recycle和连接失效(也用于支持自动重新连接),但可以在将来的版本中实现。

class sqlalchemy.pool._ConnectionFairy(dbapi_connection, connection_record, echo)

代理一个DBAPI连接并提供返回解除引用支持。

这是Pool实现用于为由Pool提供的DBAPI连接提供上下文管理的内部对象。

名字“fairy”的灵感来自于_ConnectionFairy对象的生命周期是暂时的,因为它只持续从池中检出一个特定的DBAPI连接的长度,另外作为一个透明代理,它大部分是看不见的。

也可以看看

_ConnectionRecord

_connection_record =无

对与DBAPI连接关联的_ConnectionRecord对象的引用。

这是目前的一个内部访问者,可能会有所改变。

连接 =无

对正在跟踪的实际DBAPI连接的引用。

游标 tt> * args** kwargs T5>

为基础连接返回一个新的DBAPI游标。

此方法是connection.cursor() DBAPI方法的代理。

分离 T0> ( T1> ) T2> ¶ T3>

将此连接从其池中分离出来。

这意味着关闭时连接将不再返回池,而是直接关闭。包含的ConnectionRecord与DB-API连接分开,并在下次使用时创建一个新的连接。

请注意,任何总体连接限制由池实施强加的限制可能会违反分离后,因为分离的连接从池的知识和控制中删除。

信息 T0> ¶ T1>

信息字典与该ConnectionFairy引用的底层DBAPI连接关联,允许用户定义的数据与连接相关联。

这里的数据将跟随DBAPI连接,包括在返回到连接池之后,并在_ConnectionFairy的后续实例中再次使用。它与_ConnectionRecord.infoConnection.info访问器共享。

invalidate(e=None, soft=False)

将此连接标记为无效。

此方法可以直接调用,也可以作为Connection.invalidate()方法的结果调用。调用时,DBAPI连接立即关闭,并被池中的进一步使用丢弃。失效机制通过_ConnectionRecord.invalidate()内部方法进行。

参数:
  • e - 表示无效原因的异常对象。
  • soft -

    如果为True,则连接未关闭;相反,这个连接将在下次结账时被回收。

    新版本1.0.3.

也可以看看

More on Invalidation

is_valid T0> ¶ T1>

如果_ConnectionFairy仍然引用活动的DBAPI连接,则返回True。

class sqlalchemy.pool。 _ConnectionRecord pool ) t5 > ¶ T6>

内部对象,用于维护Pool引用的单个DBAPI连接。

对于任何特定的DBAPI连接,_ConnectionRecord对象总是存在,无论该DBAPI连接是否已经“检出”。这与_ConnectionFairy形成鲜明对比,它仅在检出DBAPI连接时是公共外观。

一个_ConnectionRecord可能存在的时间跨度比单个DBAPI连接长。例如,如果调用_ConnectionRecord.invalidate()方法,则与该_ConnectionRecord关联的DBAPI连接将被丢弃,但是_ConnectionRecord可以再次使用,在这种情况下,当Pool下一个使用此记录时,会生成一个新的DBAPI连接。

连接池事件包括PoolEvents.connect()PoolEvents.checkout()一起传递_ConnectionRecord,然而_ConnectionRecord

也可以看看

_ConnectionFairy

连接 =无

对正在跟踪的实际DBAPI连接的引用。

如果_ConnectionRecord已被标记为无效,则可能为None如果拥有的池调用这个_ConnectionRecord重新连接,新的DBAPI连接可能会替换它。

信息 T0> ¶ T1>

与DBAPI连接关联的.info字典。

该字典在_ConnectionFairy.infoConnection.info访问器之间共享。

invalidate(e=None, soft=False)

使这个_ConnectionRecord持有的DBAPI连接失效。

这个方法被称为所有连接失效,包括调用_ConnectionFairy.invalidate()Connection.invalidate()方法时,以及任何所谓的“自动失效“情况发生。

参数:
  • e - 表示无效原因的异常对象。
  • soft -

    如果为True,则连接未关闭;相反,这个连接将在下次结账时被回收。

    新版本1.0.3.

也可以看看

More on Invalidation

合并纯DB-API连接

任何 PEP 249 DB-API模块都可以透明地通过连接池进行“代理”。DB-API的使用和以前一样,除了connect()方法将查询池。下面我们用psycopg2来说明:

import sqlalchemy.pool as pool
import psycopg2 as psycopg

psycopg = pool.manage(psycopg)

# then connect normally
connection = psycopg.connect(database='test', username='scott',
                             password='tiger')

这产生一个_DBProxy对象,该对象支持与原始DB-API模块相同的connect()函数。连接时,返回一个连接代理对象,它将其调用委托给一个真实的DB-API连接对象。这个连接对象持久地存储在连接池(Pool的一个实例)中,该连接池对应于发送给connect()函数的确切连接参数。

连接代理支持原始连接对象上的所有方法,其中大部分通过__getattr__()进行代理。close()方法将返回到池的连接,并且cursor()方法将返回一个代理游标对象。Both the connection proxy and the cursor proxy will also return the underlying connection to the pool after they have both been garbage collected, which is detected via weakref callbacks (__del__ is not used).

此外,当连接返回到池时,无条件地在连接上发出rollback()这是释放可能由正常活动导致的连接仍然保持的任何锁定。

默认情况下,connect()方法将返回已经在当前线程中检出的相同连接。这允许在给定的线程中使用特定的连接,而不需要在功能之间传递它。要禁止这种行为,请在manage()函数中指定use_threadlocal=False

sqlalchemy.pool.manage(module, **params)

返回一个自动池连接的DB-API模块的代理。

给定一个DB-API 2.0模块和池管理参数,为模块返回一个代理,该模块将自动汇集连接,为发送到装饰模块的connect()函数的每个不同的连接参数集创建新的连接池。

参数:
  • module – a DB-API 2.0 database module
  • poolclass – the class used by the pool module to provide pooling. 默认为QueuePool
  • **params – will be passed through to poolclass
sqlalchemy.pool。 T0> clear_managers T1> ( T2> ) T3> ¶ T4>

删除所有当前的DB-API 2.0管理器。

所有游泳池和连接都被丢弃。