1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Fixed #31090 -- Logged transaction management queries.

Thanks to Petter Strandmark for the original idea and Mariusz Felisiak
for advice during the DjangoConUS 2022 Sprint!
This commit is contained in:
Ilya Bass
2022-10-20 15:14:35 -07:00
committed by Mariusz Felisiak
parent c0a93d3941
commit 798e38c2b9
7 changed files with 109 additions and 12 deletions

View File

@@ -8,6 +8,8 @@ import warnings
from collections import deque
from contextlib import contextmanager
from django.db.backends.utils import debug_transaction
try:
import zoneinfo
except ImportError:
@@ -307,12 +309,12 @@ class BaseDatabaseWrapper:
def _commit(self):
if self.connection is not None:
with self.wrap_database_errors:
with debug_transaction(self, "COMMIT"), self.wrap_database_errors:
return self.connection.commit()
def _rollback(self):
if self.connection is not None:
with self.wrap_database_errors:
with debug_transaction(self, "ROLLBACK"), self.wrap_database_errors:
return self.connection.rollback()
def _close(self):
@@ -488,9 +490,11 @@ class BaseDatabaseWrapper:
if start_transaction_under_autocommit:
self._start_transaction_under_autocommit()
else:
elif autocommit:
self._set_autocommit(autocommit)
else:
with debug_transaction(self, "BEGIN"):
self._set_autocommit(autocommit)
self.autocommit = autocommit
if autocommit and self.run_commit_hooks_on_set_autocommit_on:

View File

@@ -13,6 +13,7 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db import IntegrityError
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.utils import debug_transaction
from django.utils.asyncio import async_unsafe
from django.utils.encoding import force_bytes, force_str
from django.utils.functional import cached_property
@@ -306,7 +307,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
def _commit(self):
if self.connection is not None:
with wrap_oracle_errors():
with debug_transaction(self, "COMMIT"), wrap_oracle_errors():
return self.connection.commit()
# Oracle doesn't support releasing savepoints. But we fake them when query

View File

@@ -144,6 +144,35 @@ class CursorDebugWrapper(CursorWrapper):
)
@contextmanager
def debug_transaction(connection, sql):
start = time.monotonic()
try:
yield
finally:
if connection.queries_logged:
stop = time.monotonic()
duration = stop - start
connection.queries_log.append(
{
"sql": "%s" % sql,
"time": "%.3f" % duration,
}
)
logger.debug(
"(%.3f) %s; args=%s; alias=%s",
duration,
sql,
None,
connection.alias,
extra={
"duration": duration,
"sql": sql,
"alias": connection.alias,
},
)
def split_tzname_delta(tzname):
"""
Split a time zone name into a 3-tuple of (name, sign, offset).