summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichail Chatzis <michatzis@gmail.com>2024-02-02 14:38:30 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-03-06 11:24:58 +0100
commit4426b1a72dc289643e2ae8c190b8dc4b3a39daf7 (patch)
tree27760cd293ea4e6dbd5a8f05dc2a443abc499f13
parent177e6493961dfcdafb44e5b02894bf4201050910 (diff)
Fixed #35021 -- Fixed capturing queries when using client-side parameters binding with psycopg 3+.
-rw-r--r--django/db/backends/postgresql/features.py9
-rw-r--r--django/db/backends/postgresql/operations.py11
-rw-r--r--django/db/backends/sqlite3/features.py3
-rw-r--r--tests/backends/base/test_base.py10
4 files changed, 30 insertions, 3 deletions
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index 809466fc7f..ef697e85b0 100644
--- a/django/db/backends/postgresql/features.py
+++ b/django/db/backends/postgresql/features.py
@@ -105,6 +105,15 @@ class DatabaseFeatures(BaseDatabaseFeatures):
},
}
)
+ if self.uses_server_side_binding:
+ skips.update(
+ {
+ "The actual query cannot be determined for server side bindings": {
+ "backends.base.test_base.ExecuteWrapperTests."
+ "test_wrapper_debug",
+ }
+ },
+ )
return skips
@cached_property
diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py
index 06981bc094..4e444d5f2b 100644
--- a/django/db/backends/postgresql/operations.py
+++ b/django/db/backends/postgresql/operations.py
@@ -296,9 +296,14 @@ class DatabaseOperations(BaseDatabaseOperations):
if is_psycopg3:
def last_executed_query(self, cursor, sql, params):
- try:
- return self.compose_sql(sql, params)
- except errors.DataError:
+ if self.connection.features.uses_server_side_binding:
+ try:
+ return self.compose_sql(sql, params)
+ except errors.DataError:
+ return None
+ else:
+ if cursor._query and cursor._query.query is not None:
+ return cursor._query.query.decode()
return None
else:
diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py
index 713d8bd38f..d95c6fb2d1 100644
--- a/django/db/backends/sqlite3/features.py
+++ b/django/db/backends/sqlite3/features.py
@@ -89,6 +89,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"db_functions.math.test_round.RoundTests."
"test_integer_with_negative_precision",
},
+ "The actual query cannot be determined on SQLite": {
+ "backends.base.test_base.ExecuteWrapperTests.test_wrapper_debug",
+ },
}
if self.connection.is_in_memory_db():
skips.update(
diff --git a/tests/backends/base/test_base.py b/tests/backends/base/test_base.py
index 03356fbf10..4418d010ea 100644
--- a/tests/backends/base/test_base.py
+++ b/tests/backends/base/test_base.py
@@ -211,6 +211,16 @@ class ExecuteWrapperTests(TestCase):
self.assertEqual(connection.execute_wrappers, [])
self.assertEqual(connections["other"].execute_wrappers, [])
+ def test_wrapper_debug(self):
+ def wrap_with_comment(execute, sql, params, many, context):
+ return execute(f"/* My comment */ {sql}", params, many, context)
+
+ with CaptureQueriesContext(connection) as ctx:
+ with connection.execute_wrapper(wrap_with_comment):
+ list(Person.objects.all())
+ last_query = ctx.captured_queries[-1]["sql"]
+ self.assertTrue(last_query.startswith("/* My comment */"))
+
class ConnectionHealthChecksTests(SimpleTestCase):
databases = {"default"}