1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #34466 -- Reallowed setting cursor_factory in DATABASES["options"] on PostgreSQL.

Regression in 09ffc5c121.
This commit is contained in:
Anders Kaseorg 2023-04-06 12:44:37 -07:00 committed by Mariusz Felisiak
parent 9daf8b4109
commit 73cbb372ba
3 changed files with 30 additions and 9 deletions

View File

@ -223,7 +223,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
conn_params.pop("assume_role", None) conn_params.pop("assume_role", None)
conn_params.pop("isolation_level", None) conn_params.pop("isolation_level", None)
conn_params.pop("server_side_binding", None) server_side_binding = conn_params.pop("server_side_binding", None)
conn_params.setdefault(
"cursor_factory",
ServerBindingCursor
if is_psycopg3 and server_side_binding is True
else Cursor,
)
if settings_dict["USER"]: if settings_dict["USER"]:
conn_params["user"] = settings_dict["USER"] conn_params["user"] = settings_dict["USER"]
if settings_dict["PASSWORD"]: if settings_dict["PASSWORD"]:
@ -269,20 +275,13 @@ class DatabaseWrapper(BaseDatabaseWrapper):
connection = self.Database.connect(**conn_params) connection = self.Database.connect(**conn_params)
if set_isolation_level: if set_isolation_level:
connection.isolation_level = self.isolation_level connection.isolation_level = self.isolation_level
if is_psycopg3: if not 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 # Register dummy loads() to avoid a round trip from psycopg2's
# decode to json.dumps() to json.loads(), when using a custom # decode to json.dumps() to json.loads(), when using a custom
# decoder in JSONField. # decoder in JSONField.
psycopg2.extras.register_default_jsonb( psycopg2.extras.register_default_jsonb(
conn_or_curs=connection, loads=lambda x: x conn_or_curs=connection, loads=lambda x: x
) )
connection.cursor_factory = Cursor
return connection return connection
def ensure_timezone(self): def ensure_timezone(self):

View File

@ -18,3 +18,7 @@ Bugfixes
* Fixed a regression in Django 4.2 that caused aggregation over query that * Fixed a regression in Django 4.2 that caused aggregation over query that
uses explicit grouping to group against the wrong columns (:ticket:`34464`). uses explicit grouping to group against the wrong columns (:ticket:`34464`).
* Reallowed, following a regression in Django 4.2, setting the
``"cursor_factory"`` option in :setting:`OPTIONS` on PostgreSQL
(:ticket:`34466`).

View File

@ -296,6 +296,24 @@ class Tests(TestCase):
finally: finally:
new_connection.close() new_connection.close()
def test_connect_custom_cursor_factory(self):
"""
A custom cursor factory can be configured with DATABASES["options"]
["cursor_factory"].
"""
from django.db.backends.postgresql.base import Cursor
class MyCursor(Cursor):
pass
new_connection = connection.copy()
new_connection.settings_dict["OPTIONS"]["cursor_factory"] = MyCursor
try:
new_connection.connect()
self.assertEqual(new_connection.connection.cursor_factory, MyCursor)
finally:
new_connection.close()
def test_connect_no_is_usable_checks(self): def test_connect_no_is_usable_checks(self):
new_connection = connection.copy() new_connection = connection.copy()
try: try: