如何在 Django 中记录所有 sql 查询?

如何记录 django 应用程序执行的所有 SQL 查询?

我想记录一切,包括来自管理站点的 SQL。我看到了 这个问题常见问题解答,但我仍然不知道我应该放在哪里

from django.db import connection
connection.queries

将所有内容记录到一个文件中?

所以我的问题是-我应该怎么做才能有一个文件(比如 all-sql)。Log)记录所有 SQL 语句的位置?

100066 次浏览

看看 https://github.com/django-debug-toolbar/django-debug-toolbar

它将让您看到由给定页面生成的所有查询。以及它们发生的地点等的堆栈痕迹。

编辑: 将所有 SQL 查询记录到一个文件等,然后需要创建一些中间件。每个请求都会运行中间件。对于这类事情,有几个姜戈的片段:

它们关心的是打印到终端,但是要使用 python 的日志库并不困难。

您需要将其放在一个中间件包中。中间件位于 webserver/django 核心和所有视图之间。它可以在请求前进行预处理,在请求完成后进行后处理。例如,将查询保存到文件中。

Django 1.3将所有 SQL 语句记录到 Django 后台日志记录器:

Https://docs.djangoproject.com/en/dev/ref/logging/#django-db-backends

在 setings.py 中添加以下粗体语句


if DEBUG:
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())



LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},'django.db.backends.sqlite3': {
'level': 'DEBUG',
'handlers': ['console'],
},
}
}
  

资源/信贷

将下面的代码片段与 settings.py中的 LOGGING字段合并:

LOGGING = {
'version': 1,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
}
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}

从@acardenas89调整回答

要在测试期间记录 SQL 查询,您需要两件事:

  1. 启用 django.db.backends日志记录器
  2. @override_settings(DEBUG=True)室内设计师。

默认情况下,测试运行程序将 设置 DEBUG = False,忽略您在 DJANGO _ SETTING _ MODULE 中可能已经设置的内容。

最低设置:

# https://docs.djangoproject.com/en/dev/ref/settings/#logging
LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
},
},
'root': {
'handlers': ['console'],
}
}

示例测试用例:

from django.contrib.auth.models import User
from django.test import TestCase, override_settings




class UserTests(TestCase):


# To log queries in tests you need to manually override DEBUG setting
# because testing sets DEBUG=False by default


@override_settings(DEBUG=True)
def test_create_user(self):
User.objects.create()

你只需:

@override_settings(DEBUG=True)

如果您已经在 runserver中打印了 SQL 调试语句。

将装饰器添加到 class TestA(TestCase)test_function:

@override_settings(DEBUG=True)
class TestA(TestCase):
...


@override_settings(DEBUG=True)
def test_function(self):
...

感谢@Janusz Skonieczny 的回答!

事实上,就我所知,在 姜戈中记录 所有 SQL 查询是不可能的。所以,记录所有 SQL 查询,你需要使用 Django 项目使用的数据库本身

例如,在 姜戈中,尝试从 Django Admin 默认使用原子事务查询“ BEGIN”和“ COMMIT”记录 所有的 SQL 查询,我通过以下 最高分@吉安马科对这个问题的回答(解答)将下面的代码添加到 “设置.py”:

"settings.py"


LOGGING = {
'version': 1,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
}
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}

但是,从 姜戈管理员,我只得到 SQL 查询记录“ SELECT”、“ UPDATE”和“ INSERT”没有 原子事务查询日志“ BEGIN”和“ COMMIT”,如下所示:

(0.000) SELECT "store_person"."id", "store_person"."first_name", "store_person"."last_name" FROM "store_person" WHERE "store_person"."id" = 33 LIMIT 21; args=(33,)
(0.000) UPDATE "store_person" SET "first_name" = 'Bill', "last_name" = 'Gates' WHERE "store_person"."id" = 33; args=('Bill', 'Gates', 33)
(0.000) INSERT INTO "django_admin_log" ("action_time", "user_id", "content_type_id", "object_id", "object_repr", "action_flag", "change_message") VALUES ('2022-08-20T13:55:19.226541+00:00'::timestamptz, 1, 20, '33', 'Bill Gates', 2, '[]') RETURNING "django_admin_log"."id"; args=(datetime.datetime(2022, 8, 20, 13, 55, 19, 226541, tzinfo=<UTC>), 1, 20, '33', 'Bill Gates', 2, '[]')

现在,例如,对于 PostgreSQL 本身,从 Django Admin 默认使用原子事务查询“ BEGIN”和“ COMMIT”记录 所有 PostgreSQL 查询,我将下面的代码添加到 在我的 Windows 11机器上,“ postgreql.conf”的结尾是“ C: Program Files PostgreSQL 14 data postgreql.conf”:

log_min_duration_statement = 0

如下所示,我将上面的代码添加到 “ postgreql.conf”的结尾:

#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------


# Add settings for extensions here
log_min_duration_statement = 0

然后,在用 姜戈管理员查询 PostgreSQL 查询之后,我可以得到的不仅仅是 SQL 查询记录“ SELECT”、“ UPDATE”和“ INSERT”,还有如下所示的 原子事务查询日志“ BEGIN”和“ COMMIT”。* 我可以打开 在我的 Windows11机器上,是“ C: Program Files PostgreSQL 14 data log postgreql-2022-08-20 _ 000000. log”查看以下日志:

2022-08-20 22:09:12.549 JST [26756] LOG:  duration: 0.025 ms  statement: BEGIN
2022-08-20 22:09:12.550 JST [26756] LOG:  duration: 1.156 ms  statement: SELECT "store_person"."id", "store_person"."first_name", "store_person"."last_name" FROM "store_person" WHERE "store_person"."id" = 33 LIMIT 21
2022-08-20 22:09:12.552 JST [26756] LOG:  duration: 0.178 ms  statement: UPDATE "store_person" SET "first_name" = 'Bill', "last_name" = 'Gates' WHERE "store_person"."id" = 33
2022-08-20 22:09:12.554 JST [26756] LOG:  duration: 0.784 ms  statement: INSERT INTO "django_admin_log" ("action_time", "user_id", "content_type_id", "object_id", "object_repr", "action_flag", "change_message") VALUES ('2022-08-20T13:09:12.553273+00:00'::timestamptz, 1, 20, '33', 'Bill Gates', 2, '[]') RETURNING "django_admin_log"."id"
2022-08-20 22:09:12.557 JST [26756] LOG:  duration: 1.799 ms  statement: COMMIT

这就是为什么 记录所有 SQL 查询,你需要使用 Django 项目使用的数据库本身

另外,我也可以用 MSSQL记录 所有 MSSQL (Microsoft SQL Server)查询,但是我不能用 SQLite记录 任何 SQLite 查询,因为看起来 SQLite没有记录 任何 SQLite 查询的功能。

此外,我还通过以下 @ geowa4的答案(解决方案) ,你的问题中也提到了将下面的代码添加到 “设置.py”中。 * 我使用的是 “姜戈 = = 3.1.7”:

# "settings.py"


from django.db import connection


print(connection.queries) # Causes error

但是,我得到了下面的错误:

django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

因此,我删除了 “ print (connection.query)”,如下所示,然后错误得到了解决,但我无法在 控制台上记录 任何 SQL 查询:

# "settings.py"


from django.db import connection


# print(connection.queries) # Causes error

如果希望通过设置可以切换这个选项,请在 setings.py 中执行以下操作:

if LOG_DB_QUERIES:
LOGGING["handlers"]["console"] = {
"level": "DEBUG", "class": "logging.StreamHandler"
}
LOGGING["loggers"]["django.db.backends"] =  {
"level": "DEBUG", "handlers": ["console"]
}
    

另外,请注意,这只有在 setings.py 中有 DEBUG = True时才有效。

感谢 @ Gian Marco的日志配置,使这个工作。