server
``connections_errors`` Number of failed connection attempts
``connections_lost`` Number of connections lost identified by
- `~ConnectionPool.check()`
+ `~ConnectionPool.check()` or by the `!check` callback
======================= =====================================================
documentation for more details.
:type open: `!bool`, default: `!True`
+ :param check: A callback to check that a connection is working correctly
+ when obtained by the pool. The callback is called at every
+ `getconn()` or `connection()`: the connection is only passed
+ to the client if the callback doesn't throw an exception.
+ By default no check is made on the connection. You can
+ provide the `check_connection()` pool static method if you
+ want to perform a simple check.
+ :type check: `Callable[[Connection], None]`
+
:param configure: A callback to configure a connection after creation.
Useful, for instance, to configure its adapters. If the
connection is used to run internal queries (to inspect the
:type num_workers: `!int`, default: 3
.. versionchanged:: 3.1
-
- added `!open` parameter to init method.
+ added `!open` parameter to the constructor.
.. versionchanged:: 3.2
+ added `!check` parameter to the constructor.
+ .. versionchanged:: 3.2
The class is generic and `!connection_class` provides types type
variable. See :ref:`pool-generic`.
returns instances of `~psycopg.AsyncConnection`, or of its subclass if
specified so in the `!connection_class` parameter.
-Only the functions with different signature from `!ConnectionPool` are
-listed here.
+Only the functions and parameters with different signature from
+`!ConnectionPool` are listed here.
.. autoclass:: AsyncConnectionPool
be an `!AsyncConnection` subclass.
:type connection_class: `!type`, default: `~psycopg.AsyncConnection`
+ :param check: A callback to check that a connection is working correctly
+ when obtained by the pool.
+ :type check: `async Callable[[Connection], None]`
+
:param configure: A callback to configure a connection after creation.
:type configure: `async Callable[[AsyncConnection], None]`
:type reconnect_failed: `Callable[[AsyncConnectionPool], None]` or
`async Callable[[AsyncConnectionPool], None]`
+ .. versionchanged:: 3.2
+ added `!check` parameter to the constructor.
+
.. versionchanged:: 3.2
The `!reconnect_failed` parameter can be `!async`.
- Add support for async `!reconnect_failed` callbacks in `AsyncConnectionPool`
(:ticket:`#520`).
-- Add `ConnectionPool.check_connection()` method.
+- Add `!check` parameter to the pool constructor and
+ `~ConnectionPool.check_connection()` method. (:ticket:`#656`).
- Make connection pool classes generic on the connection type (:ticket:`#559`).
- Raise a warning if sync pools rely an implicit `!open=True` and the
pool context is not used. In the future the default will become `!False`
------------------
- Add :ref:`null-pool` (:ticket:`#148`).
-- Add `ConnectionPool.open()` and ``open`` parameter to the pool init
+- Add `ConnectionPool.open()` and `!open` parameter to the pool constructor
(:ticket:`#151`).
- Drop support for Python 3.6.
conninfo: str = "",
*,
open: bool | None = ...,
+ check: Optional[ConnectionCB[CT]] = ...,
configure: Optional[ConnectionCB[CT]] = ...,
reset: Optional[ConnectionCB[CT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = ...,
connection_class: Type[CT],
+ check: Optional[ConnectionCB[CT]] = ...,
configure: Optional[ConnectionCB[CT]] = ...,
reset: Optional[ConnectionCB[CT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = None,
connection_class: Type[CT] = cast(Type[CT], Connection),
+ check: Optional[ConnectionCB[CT]] = None,
configure: Optional[ConnectionCB[CT]] = None,
reset: Optional[ConnectionCB[CT]] = None,
kwargs: Optional[Dict[str, Any]] = None,
conninfo,
open=open,
connection_class=connection_class,
+ check=check,
configure=configure,
reset=reset,
kwargs=kwargs,
conninfo: str = "",
*,
open: bool | None = ...,
+ check: Optional[AsyncConnectionCB[ACT]] = ...,
configure: Optional[AsyncConnectionCB[ACT]] = ...,
reset: Optional[AsyncConnectionCB[ACT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = ...,
connection_class: Type[ACT],
+ check: Optional[AsyncConnectionCB[ACT]] = ...,
configure: Optional[AsyncConnectionCB[ACT]] = ...,
reset: Optional[AsyncConnectionCB[ACT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = None,
connection_class: Type[ACT] = cast(Type[ACT], AsyncConnection),
+ check: Optional[AsyncConnectionCB[ACT]] = None,
configure: Optional[AsyncConnectionCB[ACT]] = None,
reset: Optional[AsyncConnectionCB[ACT]] = None,
kwargs: Optional[Dict[str, Any]] = None,
conninfo,
open=open,
connection_class=connection_class,
+ check=check,
configure=configure,
reset=reset,
kwargs=kwargs,
conninfo: str = "",
*,
open: bool | None = ...,
+ check: Optional[ConnectionCB[CT]] = ...,
configure: Optional[ConnectionCB[CT]] = ...,
reset: Optional[ConnectionCB[CT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = ...,
connection_class: Type[CT],
+ check: Optional[ConnectionCB[CT]] = ...,
configure: Optional[ConnectionCB[CT]] = ...,
reset: Optional[ConnectionCB[CT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = None,
connection_class: Type[CT] = cast(Type[CT], Connection),
+ check: Optional[ConnectionCB[CT]] = None,
configure: Optional[ConnectionCB[CT]] = None,
reset: Optional[ConnectionCB[CT]] = None,
kwargs: Optional[Dict[str, Any]] = None,
num_workers: int = 3,
):
self.connection_class = connection_class
+ self._check = check
self._configure = configure
self._reset = reset
return conn
def _check_connection(self, conn: CT) -> None:
- pass
+ if not self._check:
+ return
+ try:
+ self._check(conn)
+ except Exception as e:
+ logger.info("connection failed check: %s", e)
+ raise
def _maybe_grow_pool(self) -> None:
# Allow only one task at time to grow the pool (or returning
Return quietly if the connection is still working, otherwise raise
an exception.
- Used internally by `check()`, but also available for client usage.
+ Used internally by `check()`, but also available for client usage,
+ for instance as `!check` callback when a pool is created.
"""
if conn.autocommit:
conn.execute("SELECT 1")
conninfo: str = "",
*,
open: bool | None = ...,
+ check: Optional[AsyncConnectionCB[ACT]] = ...,
configure: Optional[AsyncConnectionCB[ACT]] = ...,
reset: Optional[AsyncConnectionCB[ACT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = ...,
connection_class: Type[ACT],
+ check: Optional[AsyncConnectionCB[ACT]] = ...,
configure: Optional[AsyncConnectionCB[ACT]] = ...,
reset: Optional[AsyncConnectionCB[ACT]] = ...,
kwargs: Optional[Dict[str, Any]] = ...,
*,
open: bool | None = None,
connection_class: Type[ACT] = cast(Type[ACT], AsyncConnection),
+ check: Optional[AsyncConnectionCB[ACT]] = None,
configure: Optional[AsyncConnectionCB[ACT]] = None,
reset: Optional[AsyncConnectionCB[ACT]] = None,
kwargs: Optional[Dict[str, Any]] = None,
num_workers: int = 3,
):
self.connection_class = connection_class
+ self._check = check
self._configure = configure
self._reset = reset
return conn
async def _check_connection(self, conn: ACT) -> None:
- pass
+ if not self._check:
+ return
+ try:
+ await self._check(conn)
+ except Exception as e:
+ logger.info("connection failed check: %s", e)
+ raise
def _maybe_grow_pool(self) -> None:
# Allow only one task at time to grow the pool (or returning
Return quietly if the connection is still working, otherwise raise
an exception.
- Used internally by `check()`, but also available for client usage.
+ Used internally by `check()`, but also available for client usage,
+ for instance as `!check` callback when a pool is created.
"""
if conn.autocommit:
await conn.execute("SELECT 1")
assert conn.closed
+def test_check_init(pool_cls, dsn):
+ checked = False
+
+ def check(conn):
+ nonlocal checked
+ checked = True
+
+ with pool_cls(dsn, check=check) as p:
+ with p.connection(timeout=1.0) as conn:
+ conn.execute("select 1")
+
+ assert checked
+
+
@skip_sync
def test_cancellation_in_queue(pool_cls, dsn):
# https://github.com/psycopg/psycopg/issues/509
assert conn.closed
+async def test_check_init(pool_cls, dsn):
+ checked = False
+
+ async def check(conn):
+ nonlocal checked
+ checked = True
+
+ async with pool_cls(dsn, check=check) as p:
+ async with p.connection(timeout=1.0) as conn:
+ await conn.execute("select 1")
+
+ assert checked
+
+
@skip_sync
async def test_cancellation_in_queue(pool_cls, dsn):
# https://github.com/psycopg/psycopg/issues/509