我希望对请求期间执行的每个查询进行回溯,这样我就可以找到它们来自哪里并减少计数/复杂性。
我正在使用this优秀的中间件片段来列出和计时查询,但我不知道它们来自哪里。
我已经在 django/db/models/sql/compiler.py 中进行了探索,但明显的形式是获取本地版本的 django 并编辑该代码,我看不到如何锁定查询。有我可以使用的信号吗?似乎每个查询都没有信号。
可以指定默认的吗
Manager
?
(我了解 django-toolbar,我希望有一个不使用它的解决方案。)
一个丑陋但有效的解决方案(例如,它打印所有查询的跟踪并且只需要一次编辑)是将以下内容添加到
settings.py
的底部:
import django.db.backends.utils as bakutils
import traceback
bakutils.CursorDebugWrapper_orig = bakutils.CursorWrapper
def print_stack_in_project():
stack = traceback.extract_stack()
for path, lineno, func, line in stack:
if 'lib/python' in path or 'settings.py' in path:
continue
print 'File "%s", line %d, in %s' % (path, lineno, func)
print ' %s' % line
class CursorDebugWrapperLoud(bakutils.CursorDebugWrapper_orig):
def execute(self, sql, params=None):
try:
return super(CursorDebugWrapperLoud, self).execute(sql, params)
finally:
print_stack_in_project()
print sql
print '\n\n\n'
def executemany(self, sql, param_list):
try:
return super(CursorDebugWrapperLoud, self).executemany(sql, param_list)
finally:
print_stack_in_project()
print sql
print '\n\n\n'
bakutils.CursorDebugWrapper = CursorDebugWrapperLoud
仍然不确定是否有更优雅的方法来做到这一点?
Django 调试工具栏会以惊人的方式告诉您您想要什么。
您可以像这样自定义 Django 的
LOGGING
设置,以在每个记录的查询上输出回溯,以及 logging.StreamHandler
的通常输出:
import logging
import traceback
class TracebackHandler(logging.StreamHandler):
def emit(self, record):
traceback.print_stack()
super().emit(record)
LOGGING = {
"version": 1,
"handlers": {
"traceback": {"class": f"{__name__}.TracebackHandler"},
},
"loggers": {
"django.db": {
"handlers": ["traceback"],
"level": "DEBUG",
},
},
}