summaryrefslogtreecommitdiff
path: root/django/db/backends/postgresql/base.py
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-16 10:22:02 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-17 08:24:08 +0100
commit0e2649fdf40cedc5be7e2c0e5f7711f315e36b84 (patch)
treee970a4cd9f3bd3d26f888c7c1342af753b440dcf /django/db/backends/postgresql/base.py
parentc8a76059ff6ff37fb51972fe2ba8b9d9464af769 (diff)
downloaddjango-0e2649fdf40cedc5be7e2c0e5f7711f315e36b84.tar.gz
Fixed #34255 -- Made PostgreSQL backend use client-side parameters binding with psycopg version 3.
Thanks Guillaume Andreu Sabater for the report. Co-authored-by: Florian Apolloner <apollo13@users.noreply.github.com>
Diffstat (limited to 'django/db/backends/postgresql/base.py')
-rw-r--r--django/db/backends/postgresql/base.py19
1 files changed, 16 insertions, 3 deletions
diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py
index 34a98e9e3a..9e24b186cf 100644
--- a/django/db/backends/postgresql/base.py
+++ b/django/db/backends/postgresql/base.py
@@ -223,6 +223,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
conn_params.pop("assume_role", None)
conn_params.pop("isolation_level", None)
+ conn_params.pop("server_side_binding", None)
if settings_dict["USER"]:
conn_params["user"] = settings_dict["USER"]
if settings_dict["PASSWORD"]:
@@ -268,14 +269,20 @@ class DatabaseWrapper(BaseDatabaseWrapper):
connection = self.Database.connect(**conn_params)
if set_isolation_level:
connection.isolation_level = self.isolation_level
- if not is_psycopg3:
+ if is_psycopg3:
+ connection.cursor_factory = (
+ ServerBindingCursor
+ if options.get("server_side_binding") is True
+ else Cursor
+ )
+ else:
# Register dummy loads() to avoid a round trip from psycopg2's
# decode to json.dumps() to json.loads(), when using a custom
# decoder in JSONField.
psycopg2.extras.register_default_jsonb(
conn_or_curs=connection, loads=lambda x: x
)
- connection.cursor_factory = Cursor
+ connection.cursor_factory = Cursor
return connection
def ensure_timezone(self):
@@ -436,7 +443,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
if is_psycopg3:
- class Cursor(Database.Cursor):
+ class CursorMixin:
"""
A subclass of psycopg cursor implementing callproc.
"""
@@ -457,6 +464,12 @@ if is_psycopg3:
self.execute(stmt)
return args
+ class ServerBindingCursor(CursorMixin, Database.Cursor):
+ pass
+
+ class Cursor(CursorMixin, Database.ClientCursor):
+ pass
+
class CursorDebugWrapper(BaseCursorDebugWrapper):
def copy(self, statement):
with self.debug_sql(statement):