Django 查询回溯

问题描述 投票:0回答:3

我希望对请求期间执行的每个查询进行回溯,这样我就可以找到它们来自哪里并减少计数/复杂性。

我正在使用this优秀的中间件片段来列出和计时查询,但我不知道它们来自哪里。

我已经在 django/db/models/sql/compiler.py 中进行了探索,但明显的形式是获取本地版本的 django 并编辑该代码,我看不到如何锁定查询。有我可以使用的信号吗?似乎每个查询都没有信号

可以指定默认的吗

Manager

(我了解 django-toolbar,我希望有一个不使用它的解决方案。)

sql django performance django-models backtrace
3个回答
8
投票

一个丑陋但有效的解决方案(例如,它打印所有查询的跟踪并且只需要一次编辑)是将以下内容添加到

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

仍然不确定是否有更优雅的方法来做到这一点?


1
投票

Django 调试工具栏会以惊人的方式告诉您您想要什么。


0
投票

您可以像这样自定义 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",
        },
    },
}
© www.soinside.com 2019 - 2024. All rights reserved.