--- /dev/null
- :show-inheritance:
+ .. _pooling_toplevel:
+
+ Connection Pooling
+ ==================
+
+ .. module:: sqlalchemy.pool
+
+ The establishment of a
+ database connection is typically a somewhat expensive operation, and
+ applications need a way to get at database connections repeatedly
+ with minimal overhead. Particularly for
+ server-side web applications, a connection pool is the standard way to
+ maintain a "pool" of active database connections in memory which are
+ reused across requests.
+
+ SQLAlchemy includes several connection pool implementations
+ which integrate with the :class:`.Engine`. They can also be used
+ directly for applications that want to add pooling to an otherwise
+ plain DBAPI approach.
+
+ Connection Pool Configuration
+ -----------------------------
+
+ The :class:`~sqlalchemy.engine.Engine` returned by the
+ :func:`~sqlalchemy.create_engine` function in most cases has a :class:`QueuePool`
+ integrated, pre-configured with reasonable pooling defaults. If
+ you're reading this section to simply enable pooling- congratulations!
+ You're already done.
+
+ The most common :class:`QueuePool` tuning parameters can be passed
+ directly to :func:`~sqlalchemy.create_engine` as keyword arguments:
+ ``pool_size``, ``max_overflow``, ``pool_recycle`` and
+ ``pool_timeout``. For example::
+
+ engine = create_engine('postgresql://me@localhost/mydb',
+ pool_size=20, max_overflow=0)
+
+ In the case of SQLite, a :class:`SingletonThreadPool` is provided instead,
+ to provide compatibility with SQLite's restricted threading model, as well
+ as to provide a reasonable default behavior to SQLite "memory" databases,
+ which maintain their entire dataset within the scope of a single connection.
+
+ All SQLAlchemy pool implementations have in common
+ that none of them "pre create" connections - all implementations wait
+ until first use before creating a connection. At that point, if
+ no additional concurrent checkout requests for more connections
+ are made, no additional connections are created. This is why it's perfectly
+ fine for :func:`.create_engine` to default to using a :class:`.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.
+
+ Switching Pool Implementations
+ ------------------------------
+
+ The usual way to use a different kind of pool with :func:`.create_engine`
+ is to use the ``poolclass`` argument. This argument accepts a class
+ imported from the ``sqlalchemy.pool`` module, and handles the details
+ of building the pool for you. Common options include specifying
+ :class:`.QueuePool` with SQLite::
+
+ from sqlalchemy.pool import QueuePool
+ engine = create_engine('sqlite:///file.db', poolclass=QueuePool)
+
+ Disabling pooling using :class:`.NullPool`::
+
+ from sqlalchemy.pool import NullPool
+ engine = create_engine(
+ 'postgresql+psycopg2://scott:tiger@localhost/test',
+ poolclass=NullPool)
+
+ Using a Custom Connection Function
+ ----------------------------------
+
+ All :class:`.Pool` classes accept an argument ``creator`` which is
+ a callable that creates a new connection. :func:`.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)
+
+ For most "initialize on connection" routines, it's more convenient
+ to use a :class:`.PoolListener`, so that the usual URL argument to
+ :func:`.create_engine` is still usable. ``creator`` is there as
+ a total last resort for when a DBAPI has some form of ``connect``
+ that is not at all supported by SQLAlchemy.
+
+ Constructing a Pool
+ ------------------------
+
+ To use a :class:`.Pool` by itself, the ``creator`` function is
+ the only argument that's required and is passed first, followed
+ by any additional options::
+
+ 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 connections can then be procured from the pool using the :meth:`.Pool.connect`
+ function. The return value of this method is a DBAPI connection that's contained
+ within a transparent proxy::
+
+ # get a connection
+ conn = mypool.connect()
+
+ # use it
+ cursor = conn.cursor()
+ cursor.execute("select foo")
+
+ The purpose of the transparent proxy is to intercept the ``close()`` call,
+ such that instead of the DBAPI connection being closed, its returned to the
+ pool::
+
+ # "close" the connection. Returns
+ # it to the pool.
+ conn.close()
+
+ The proxy also returns its contained DBAPI connection to the pool
+ when it is garbage collected,
+ though it's not deterministic in Python that this occurs immediately (though
+ it is typical with cPython).
+
+ A particular pre-created :class:`.Pool` can be shared with one or more
+ engines by passing it to the ``pool`` argument of :func:`.create_engine`::
+
+ e = create_engine('postgresql://', pool=mypool)
+
+ Pool Event Listeners
+ --------------------
+
+ Connection pools support an event interface that allows hooks to execute
+ upon first connect, upon each new connection, and upon checkout and
+ checkin of connections. See :class:`.PoolListener` for details.
+
+ Builtin Pool Implementations
+ ----------------------------
+
+ .. autoclass:: sqlalchemy.pool.Pool
+
+ .. automethod:: __init__
+ .. automethod:: connect
+ .. automethod:: dispose
+ .. automethod:: recreate
+
+ .. autoclass:: sqlalchemy.pool.QueuePool
+ :show-inheritance:
+
+ .. automethod:: __init__
+
+ .. autoclass:: SingletonThreadPool
+ :show-inheritance:
+
+ .. automethod:: __init__
+
+ .. autoclass:: AssertionPool
+ :show-inheritance:
+
+ .. autoclass:: NullPool
++ :show-inheritance:
+
+ .. autoclass:: StaticPool
+ :show-inheritance:
+
+
+ Pooling Plain DB-API Connections
+ --------------------------------
+
+ Any :pep:`249` DB-API module can be "proxied" through the connection
+ pool transparently. Usage of the DB-API is exactly as before, except
+ the ``connect()`` method will consult the pool. Below we illustrate
+ this with ``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')
+
+ This produces a :class:`_DBProxy` object which supports the same
+ ``connect()`` function as the original DB-API module. Upon
+ connection, a connection proxy object is returned, which delegates its
+ calls to a real DB-API connection object. This connection object is
+ stored persistently within a connection pool (an instance of
+ :class:`Pool`) that corresponds to the exact connection arguments sent
+ to the ``connect()`` function.
+
+ The connection proxy supports all of the methods on the original
+ connection object, most of which are proxied via ``__getattr__()``.
+ The ``close()`` method will return the connection to the pool, and the
+ ``cursor()`` method will return a proxied cursor object. 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).
+
+ Additionally, when connections are returned to the pool, a
+ ``rollback()`` is issued on the connection unconditionally. This is
+ to release any locks still held by the connection that may have
+ resulted from normal activity.
+
+ By default, the ``connect()`` method will return the same connection
+ that is already checked out in the current thread. This allows a
+ particular connection to be used in a given thread without needing to
+ pass it around between functions. To disable this behavior, specify
+ ``use_threadlocal=False`` to the ``manage()`` function.
+
+ .. autofunction:: sqlalchemy.pool.manage
+
+ .. autofunction:: sqlalchemy.pool.clear_managers
+