Skip to content

Commit 32ab363

Browse files
committed
Fix psycopg3 tests
Several tests (such as SQLPanelTestCase.test_cursor_wrapper_singleton) are written to ensure that only a single cursor wrapper is instantiated during the test. However, this fails when using Django's psycopg3 backend, since the .last_executed_query() call in NormalCursorWrapper._record() ends up creating an additional cursor (via [1]). To avoid this wrapping this additional cursor, set the DatabaseWrapper's ._djdt_logger attribute to None before calling .last_executed_query() and restore it when finished. This will cause the monkey-patched DatabaseWrapper .cursor() and .chunked_cursor() methods to return the original cursor without wrapping during that call. [1] https://github.com/django/django/blob/4.2.1/django/db/backends/postgresql/psycopg_any.py#L21
1 parent 217238b commit 32ab363

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

debug_toolbar/panels/sql/tracking.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,21 @@ def _decode(self, param):
144144
except UnicodeDecodeError:
145145
return "(encoded string)"
146146

147+
def _last_executed_query(self, sql, params):
148+
"""Get the last executed query from the connection."""
149+
# Django's psycopg3 backend creates a new cursor in its implementation of the
150+
# .last_executed_query() method. To avoid wrapping that cursor, temporarily set
151+
# the DatabaseWrapper's ._djdt_logger attribute to None. This will cause the
152+
# monkey-patched .cursor() and .chunked_cursor() methods to skip the wrapping
153+
# process during the .last_executed_query() call.
154+
self.db._djdt_logger = None
155+
try:
156+
return self.db.ops.last_executed_query(
157+
self.cursor, sql, self._quote_params(params)
158+
)
159+
finally:
160+
self.db._djdt_logger = self.logger
161+
147162
def _record(self, method, sql, params):
148163
alias = self.db.alias
149164
vendor = self.db.vendor
@@ -176,17 +191,17 @@ def _record(self, method, sql, params):
176191
params = {
177192
"vendor": vendor,
178193
"alias": alias,
179-
"sql": self.db.ops.last_executed_query(
180-
self.cursor, sql, self._quote_params(params)
181-
),
194+
"sql": self._last_executed_query(sql, params),
182195
"duration": duration,
183196
"raw_sql": sql,
184197
"params": _params,
185198
"raw_params": params,
186199
"stacktrace": get_stack_trace(skip=2),
187200
"start_time": start_time,
188201
"stop_time": stop_time,
189-
"is_slow": duration > dt_settings.get_config()["SQL_WARNING_THRESHOLD"],
202+
"is_slow": (
203+
duration > dt_settings.get_config()["SQL_WARNING_THRESHOLD"]
204+
),
190205
"is_select": sql.lower().strip().startswith("select"),
191206
"template_info": template_info,
192207
}

0 commit comments

Comments
 (0)