在保留 settings.DEBUG 的同时关闭 SQL 日志记录?

Posted

技术标签:

【中文标题】在保留 settings.DEBUG 的同时关闭 SQL 日志记录?【英文标题】:turn off SQL logging while keeping settings.DEBUG? 【发布时间】:2011-12-07 18:09:06 【问题描述】:

当 settings.DEBUG=True 时,Django 将 SQL 操作记录到内部缓冲区(无论是否记录到文件)。因为我有一个执行大量数据库操作的长时间运行的进程,这会导致我的程序开发模式实例的内存消耗增长得非常快。

我想在保留设置的同时禁用内部 SQL 日志记录机制。为我的开发打开调试:这可能吗?

Django 版本 1.3.0。

【问题讨论】:

【参考方案1】:

是的,您可以通过为名为“django.db.backends”的记录器分配一个“空处理程序”来使 sql 日志停止。我假设您使用django's new dict-based logging setup?如果是这样,这个 sn-p 应该很容易:

    ...
    'handlers': 
        'null': 
            'level': 'DEBUG',
            'class':'logging.NullHandler',
            ,
    ...
    'loggers': 
        ... your regular logger 'root' or '' ....
        'django.db.backends': 
            'handlers': ['null'],  # Quiet by default!
            'propagate': False,
            'level':'DEBUG',
            ,
    ...

更新:也请看一下 Brian 的回答。我将“日志记录”理解为每个 sql 语句的令人讨厌的日志记录。 Brian 谈到了每个查询的内部内存记录(我猜他是对的 :-)

【讨论】:

很好的答案,这更容易,并解决了 DEBUG=True 模式下最常见的日志文件被 SQL 语句阻塞的问题。 我使用的 Django 版本 (1.9) - 而不是 'handlers':['null'] 我替换为 None 所以 'handlers':None 在 Django >= 1.9 的版本中,django.utils.log.NullHandler 不再存在。请改用logging.NullHandler【参考方案2】:

当 settings.DEBUG 为 True 时,Django 使用 CursorDebugWrapper 而不是 CursorWrapper。这就是将查询附加到 connection.queries 并消耗内存的原因。我会猴子修补连接包装器以始终使用 CursorWrapper:

from django.conf import settings
from django.db.backends import BaseDatabaseWrapper
from django.db.backends.util import CursorWrapper

if settings.DEBUG:
    BaseDatabaseWrapper.make_debug_cursor = lambda self, cursor: CursorWrapper(cursor, self)

像其他人建议的那样禁用日志记录并不能解决问题,因为即使日志记录关闭,CursorDebugWrapper 仍将查询存储在 connection.queries 中。

【讨论】:

这个去哪儿了?如果我将其添加到 settings.py 中,我会在尝试执行 from django.db.backends import BaseDatabaseWrapper 时得到以下 ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined. 在最近的 Django 版本中,导入路径发生了变化:from django.db.backends.base.base import BaseDatabaseWrapperfrom django.db.backends.utils import CursorWrapper【参考方案3】:

这对我有用(至少对于 Django 1.3.1):

from django.db import connection
connection.use_debug_cursor = False

我发现检查 Django 源代码的变量(没有记录),相关行在 django/db/backends/__init__.pyBaseDatabaseWrapper 类)中找到:

def cursor(self):
    if (self.use_debug_cursor or
        (self.use_debug_cursor is None and settings.DEBUG)):
        cursor = self.make_debug_cursor(self._cursor())
    else:
        cursor = util.CursorWrapper(self._cursor(), self)
    return cursor

【讨论】:

【参考方案4】:

如果仍然对跟踪 SQL 操作以进行调试感兴趣,您还可以定期清理 connection.queries 列表以回收内存:

from django.db import connection

for i in range(start, count, size):
    objects = MyModel.objects.order_by('pk').all()[i:i + size]
    ...
    print connection.queries
    connection.queries = []

【讨论】:

【参考方案5】:

Django 3.0.7

改变

def queries_logged(self):
    self.force_debug_cursor or settings.DEBUG

def queries_logged(self):
    return False

在 django/db/backends/base/db.py 中

【讨论】:

以上是关于在保留 settings.DEBUG 的同时关闭 SQL 日志记录?的主要内容,如果未能解决你的问题,请参考以下文章

settings.DEBUG 的值在 Django 测试中的设置和 url 之间变化

关闭模式视图但保留数据

在保持关闭按钮的同时隐藏我的对话框标题栏时遇到问题

开启安卓的不保留活动选项后,手机所有程序包括相机全部闪退。。。。现在设置也进不去,如何关闭该选项

你如何在 django 网站上记录服务器错误

即使在数据关闭后,我如何编码以保留数据?