``connections_lost`` Number of connections lost identified by
`~ConnectionPool.check()` or by the `!check` callback
======================= =====================================================
+
+
+.. _pool-sqlalchemy:
+
+Integration with SQLAlchemy
+---------------------------
+
+.. versionadded:: 3.3
+
+If you want to use SQLAlchemy__ with psycopg's connection pool you can use the
+SQLAlchemy's NullPool__ feature, using the pool's `~ConnectionPool.getconn`
+as `!creator` function. However, SQLAlchemy expects that calling
+`~psycopg.Connection.close()` on the connection will return the connection to
+the pool, which is not Psycopg's default behaviour.
+
+.. __: https://sqlalchemy.org
+.. __: https://docs.sqlalchemy.org/en/20/core/pooling.html#sqlalchemy.pool.NullPool
+
+Since `!psycopg_pool` version 3.3, the `!close_returns` parameter of the pool
+allows to change this behaviour, telling its connections to return to the
+pool, instead of closing, when `!close()` is called.
+
+For example:
+
+.. code:: python
+
+ import sqlalchemy.pool
+ import psycopg_pool
+
+ db_url = "postgresql://postgres:postgres@hostname:port/database"
+
+ pgpool = psycopg_pool.ConnectionPool(conninfo=db_url, close_returns=True)
+
+ engine = sqlalchemy.create_engine(
+ url=db_url.replace("postgresql://", "postgresql+psycopg://"),
+ poolclass=sqlalchemy.pool.NullPool,
+ creator=pgpool.getconn,
+ )
+
+If you want to integrate the Psycopg pool with SQLAlchemy using a `!psycopg_pool`
+version older than 3.3, you will need to create a subclass of the
+`~psycopg.Connection` or `~psycopg.AsyncConnection` class, overriding the
+`!close()` method, with an implementation similar to the following:
+
+.. code:: python
+
+ class MyConnection(psycopg.AsyncConnection):
+ # If you need to subclass a sync connection, just drop the
+ # 'async' and 'await' keywords from this example.
+ async def close(self) -> None:
+ if pool := getattr(self, "_pool", None):
+ # Connection currently checked out from the pool.
+ # Instead of closing it, return it to the pool.
+ await pool.putconn(self)
+ else:
+ # Connection not part of any pool, or currently into the pool.
+ # Close the connection for real.
+ await super().close()
+
+
+Using a connection implementing this method you will not need to specify
+`!close_returns` in the pool constructor, but just `!connection_class`; the
+example above would be modified as:
+
+.. code:: python
+
+ pgpool = psycopg_pool.ConnectionPool(conninfo=db_url, connection_class=MyConnection)
want to perform a simple check.
:type check: `Callable[[Connection], None]`
+ :param close_returns: If `!True`, calling `~psycopg.Connection.close()` on
+ the connection will not actually close it, but it
+ will return the connection to the pool, like in
+ `~ConnectionPool.putconn()`. Use it if you want to
+ use Psycopg pool with SQLAlchemy. See
+ :ref:`pool-sqlalchemy`.
+
+ :type close_returns: `!bool`, default: `!False`
+
:param reset: A callback to reset a function after it has been returned to
the pool. The connection is guaranteed to be passed to the
`!reset()` function in "idle" state (no transaction). When
added `!check` parameter to the constructor.
.. versionchanged:: 3.2
- The class is generic and `!connection_class` provides types type
+ the class is generic and `!connection_class` provides types type
variable. See :ref:`pool-generic`.
+ .. versionchanged:: 3.3
+ added `!close_returns` parameter to the constructor.
+
.. warning::
At the moment, the default value for the `!open` parameter is `!True`;
.. versionchanged:: 3.2
The `!reconnect_failed` parameter can be `!async`.
+ .. versionchanged:: 3.3
+ added `!close_returns` parameter to the constructor.
+
.. warning::
Opening an async pool in the constructor (using `!open=True` on init)