From: Daniele Varrazzo Date: Mon, 8 Apr 2024 20:22:02 +0000 (+0000) Subject: feat(prepare): allow setting connection.prepare_max to None X-Git-Tag: 3.2.0~55^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F773%2Fhead;p=thirdparty%2Fpsycopg.git feat(prepare): allow setting connection.prepare_max to None --- diff --git a/docs/advanced/prepare.rst b/docs/advanced/prepare.rst index 32309a306..25f98a51c 100644 --- a/docs/advanced/prepare.rst +++ b/docs/advanced/prepare.rst @@ -48,6 +48,12 @@ Statement preparation can be controlled in several ways: .. __: https://www.postgresql.org/docs/current/sql-prepare.html + +.. _pgbouncer: + +Using prepared statements with PgBouncer +---------------------------------------- + .. warning:: Unless a connection pooling middleware explicitly declares otherwise, they @@ -56,12 +62,6 @@ Statement preparation can be controlled in several ways: is used you should disable prepared statements, by setting the `Connection.prepare_threshold` attribute to `!None`. - -.. _pgbouncer: - -Using prepared statements with PgBouncer ----------------------------------------- - Starting from 3.2, Psycopg supports prepared statements when using the PgBouncer__ middleware, using the following caveats: @@ -78,4 +78,4 @@ PgBouncer__ middleware, using the following caveats: If libpq 17 is not available on your client, but PgBouncer is 1.22 or higher, you can still use Psycopg *as long as you disable deallocation*. - You can do so by setting `Connection.prepared_max` to `!sys.maxsize`. + You can do so by setting `Connection.prepared_max` to `!None`. diff --git a/docs/api/connections.rst b/docs/api/connections.rst index 898a8470d..11f29a8b9 100644 --- a/docs/api/connections.rst +++ b/docs/api/connections.rst @@ -273,8 +273,15 @@ The `!Connection` class If more queries need to be prepared, old ones are deallocated__. + Specifying `!None` can be useful for middleware that don't support + deallocation; see :ref:`prepared statements notes `. + .. __: https://www.postgresql.org/docs/current/sql-deallocate.html + .. versionchanged:: 3.2 + + Added support for the `!None` value. + .. rubric:: Methods you can use to do something cool diff --git a/psycopg/psycopg/_connection_base.py b/psycopg/psycopg/_connection_base.py index a5fe327da..013c0c10c 100644 --- a/psycopg/psycopg/_connection_base.py +++ b/psycopg/psycopg/_connection_base.py @@ -4,6 +4,7 @@ psycopg connection objects # Copyright (C) 2020 The Psycopg Team +import sys import logging from typing import Callable, Generic from typing import List, NamedTuple, Optional, Tuple, Union @@ -398,16 +399,20 @@ class BaseConnection(Generic[Row]): self._prepared.prepare_threshold = value @property - def prepared_max(self) -> int: + def prepared_max(self) -> Optional[int]: """ Maximum number of prepared statements on the connection. - Default value: 100 + `!None` means no max number of prepared statements. The default value + is 100. """ - return self._prepared.prepared_max + rv = self._prepared.prepared_max + return rv if rv != sys.maxsize else None @prepared_max.setter - def prepared_max(self, value: int) -> None: + def prepared_max(self, value: Optional[int]) -> None: + if value is None: + value = sys.maxsize self._prepared.prepared_max = value # Generators to perform high-level operations on the connection diff --git a/tests/test_prepared.py b/tests/test_prepared.py index 39dff56cc..1dd4e9534 100644 --- a/tests/test_prepared.py +++ b/tests/test_prepared.py @@ -5,6 +5,7 @@ Prepared statements tests """ +import sys import logging import datetime as dt from decimal import Decimal @@ -199,6 +200,24 @@ def test_deallocate_or_close(conn, caplog): assert "DEALLOCATE" in msgs +def test_prepared_max_none(conn): + conn.prepared_max = 42 + assert conn.prepared_max == 42 + assert conn._prepared.prepared_max == 42 + + conn.prepared_max = None + assert conn._prepared.prepared_max == sys.maxsize + assert conn.prepared_max is None + + conn.prepared_max = 0 + assert conn._prepared.prepared_max == 0 + assert conn.prepared_max == 0 + + conn.prepared_max = 24 + assert conn.prepared_max == 24 + assert conn._prepared.prepared_max == 24 + + def test_different_types(conn): conn.prepare_threshold = 0 conn.execute("select %s", [None])