aboutsummaryrefslogtreecommitdiffstats
path: root/debug_toolbar/panels/sql.py
diff options
context:
space:
mode:
authorRob Hudson2009-08-28 09:21:39 -0700
committerRob Hudson2009-08-28 09:21:39 -0700
commitf97ff555a4d8f22dae83bcfd0c2dcf6e846962c9 (patch)
tree668ce76df028ebf37de98e48a022e7bbdb844151 /debug_toolbar/panels/sql.py
parent4a59813e75d7cb3b88bf2b223b21d4e23d9ecb03 (diff)
downloaddjango-debug-toolbar-f97ff555a4d8f22dae83bcfd0c2dcf6e846962c9.tar.bz2
Refactored SQL panel to use datetime objects and added a visual display of both duration and sequence to the SQL template.
Diffstat (limited to 'debug_toolbar/panels/sql.py')
-rw-r--r--debug_toolbar/panels/sql.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py
index f12939e..62c0e58 100644
--- a/debug_toolbar/panels/sql.py
+++ b/debug_toolbar/panels/sql.py
@@ -1,6 +1,6 @@
import os
import SocketServer
-import time
+from datetime import datetime
import traceback
import django
from django.conf import settings
@@ -16,6 +16,10 @@ from debug_toolbar.panels import DebugPanel
django_path = os.path.realpath(os.path.dirname(django.__file__))
socketserver_path = os.path.realpath(os.path.dirname(SocketServer.__file__))
+# TODO:This should be set in the toolbar loader as a default and panels should
+# get a copy of the toolbar object with access to its config dictionary
+SQL_WARNING_THRESHOLD = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {}).get('SQL_WARNING_THRESHOLD', 500)
+
def tidy_stacktrace(strace):
"""
Clean up stacktrace and remove all entries that:
@@ -39,11 +43,12 @@ class DatabaseStatTracker(util.CursorDebugWrapper):
in `connection.queries`.
"""
def execute(self, sql, params=()):
- start = time.time()
+ start = datetime.now()
try:
return self.cursor.execute(sql, params)
finally:
- stop = time.time()
+ stop = datetime.now()
+ duration = ms_from_timedelta(stop - start)
stacktrace = tidy_stacktrace(traceback.extract_stack())
_params = ''
try:
@@ -53,11 +58,14 @@ class DatabaseStatTracker(util.CursorDebugWrapper):
# We keep `sql` to maintain backwards compatibility
self.db.queries.append({
'sql': self.db.ops.last_executed_query(self.cursor, sql, params),
- 'time': (stop - start) * 1000, # convert to ms
+ 'duration': duration,
'raw_sql': sql,
'params': _params,
'hash': sha_constructor(settings.SECRET_KEY + sql + _params).hexdigest(),
'stacktrace': stacktrace,
+ 'start_time': start,
+ 'stop_time': stop,
+ 'is_slow': (duration > SQL_WARNING_THRESHOLD)
})
util.CursorDebugWrapper = DatabaseStatTracker
@@ -77,14 +85,14 @@ class SQLDebugPanel(DebugPanel):
return 'SQL'
def nav_subtitle(self):
- self._sql_time = sum(map(lambda q: float(q['time']), connection.queries))
+ self._sql_time = sum([q['duration'] for q in connection.queries[self._offset:]])
num_queries = len(connection.queries) - self._offset
return "%d %s in %.2fms" % (
num_queries,
(num_queries == 1) and 'query' or 'queries',
self._sql_time
)
-
+
def title(self):
return 'SQL Queries'
@@ -93,8 +101,15 @@ class SQLDebugPanel(DebugPanel):
def content(self):
sql_queries = connection.queries[self._offset:]
+ width_ratio_tally = 0
for query in sql_queries:
query['sql'] = reformat_sql(query['sql'])
+ try:
+ query['width_ratio'] = (query['duration'] / self._sql_time) * 100
+ except ZeroDivisionError:
+ query['width_ratio'] = 0
+ query['start_offset'] = width_ratio_tally
+ width_ratio_tally += query['width_ratio']
context = {
'queries': sql_queries,
@@ -103,6 +118,12 @@ class SQLDebugPanel(DebugPanel):
}
return render_to_string('debug_toolbar/panels/sql.html', context)
+def ms_from_timedelta(td):
+ """
+ Given a timedelta object, returns a float representing milliseconds
+ """
+ return (td.seconds * 1000) + (td.microseconds / 1000.0)
+
def reformat_sql(sql):
sql = sql.replace(',', ', ')
sql = sql.replace('SELECT ', 'SELECT\n\t')