]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
feat(prepare): allow setting connection.prepare_max to None 773/head
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 8 Apr 2024 20:22:02 +0000 (20:22 +0000)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 8 Apr 2024 21:22:05 +0000 (23:22 +0200)
docs/advanced/prepare.rst
docs/api/connections.rst
psycopg/psycopg/_connection_base.py
tests/test_prepared.py

index 32309a3061aab7501ac743efbb700004dfc7ab6c..25f98a51c39b6fbb99a83ecdaca549111c3eafe9 100644 (file)
@@ -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`.
index 898a8470d4da756a3567b753b85571437cad1bb7..11f29a8b93e4e025d9a69db55fef51d136b5243a 100644 (file)
@@ -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 <pgbouncer>`.
+
         .. __: 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
 
index a5fe327da513c9e436756fc1e87471df5b513fd0..013c0c10c97a308a68c45814a6179b1b4a399334 100644 (file)
@@ -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
index 39dff56cc5f9aaa8c128c3d2179f824ac36dfb15..1dd4e9534dacd7c4271d64b844b2885cdb771415 100644 (file)
@@ -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])