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

2025-02-10 08:57:00
admin
原创
52
摘要:问题描述:如何记录我的 django 应用程序执行的所有 SQL 查询?我想记录所有内容,包括来自管理站点的 SQL。我看到了这个问题和常见问题解答,但我仍然不知道应该把这些放在哪里from django.db import connection connection.queries 将所有内容记录到一个文件...

问题描述:

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

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

from django.db import connection
connection.queries

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

所以我的问题是 - 我应该怎么做才能得到一个记录所有 SQL 语句的文件(比如说 all-sql.log)?


解决方案 1:

将以下代码片段与LOGGING您的字段合并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'],
        }
    }
}

根据@acardenas89 的回答修改

解决方案 2:

在settings.py中添加以下加粗语句


如果调试:
    导入日志
    l = logs.getLogger('django.db.backends') 复制代码
    l.设置级别(日志记录.DEBUG)
    添加Handler(logging.StreamHandler())


记录 = {
    ‘版本’:1,
    ‘disable_existing_loggers’:false,
    ‘过滤器’:{
        ‘需要_debug_false’:{
            '()':'django.utils.log.RequireDebugFalse'
        }
    },
    ‘处理程序’:{
        ‘邮件管理员’:{
            ‘级别’:‘错误’,
            ‘过滤器’:[‘require_debug_false’],
            ‘类’:‘django.utils.log.AdminEmailHandler’
        },'安慰': {
            ‘级别’:‘调试’,
            ‘类’:‘logging.StreamHandler’,
        },
    },
    ‘记录员’:{
        ‘django.request’:{
            ‘处理程序’:[‘mail_admins’],
            ‘级别’:‘错误’,
            ‘传播’:真实,
        }, 'django.db.backends.sqlite3': {
            ‘级别’:‘调试’,
            ‘处理程序’:[‘控制台’],
        },
    }
}
  

资源/信用

解决方案 3:

要在测试期间记录 SQL 查询,您需要两样东西:

  1. django.db.backends记录器已启用并且

  2. @override_settings(DEBUG=True) 装饰器。

测试运行器将默认设置 DEBUG=False ,忽略您在 DJANGO_SETTINGS_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()

解决方案 4:

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

它会让您看到给定页面生成的所有查询。以及它们发生位置的堆栈跟踪等。

编辑:要将所有 SQL 查询记录到文件等,那么您需要创建一些中间件。中间件在每个请求时运行。有几种 Django 代码片段可用于此类操作:

这些与打印到终端有关,但调整它们以使用 python 的日志库并不难。

解决方案 5:

Django 1.3 将所有 SQL 语句记录到django.db.backends记录器:

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

解决方案 6:

在现代 Django 中,我们拥有了原生的方式来挂钩和检测 SQL 查询,而无需安装额外的依赖项。OP 要求所有查询,但这也可以用于高情境用途。

import time

class QueryLogger:
    def __init__(self):
        self.queries = []

    def __call__(self, execute, sql, params, many, context):
        current_query = {"sql": sql, "params": params, "many": many}
        start = time.monotonic()
        try:
            result = execute(sql, params, many, context)
        except Exception as e:
            current_query["status"] = "error"
            current_query["exception"] = e
            raise
        else:
            current_query["status"] = "ok"
            return result
        finally:
            duration = time.monotonic() - start
            current_query["duration"] = duration
            self.queries.append(current_query)
(...)

# say, in Django Shell we would like to see 
# whether .exists() is faster than .count() 
# and what raw SQL it actually runs

import pprint
from django.db import connection
    
ql = QueryLogger()
with connection.execute_wrapper(ql):
    Book.objects.filter(author="Uncle Bob").exists()
    Book.objects.filter(author="Uncle Bob").count()

pprint.pprint(ql.queries)

解决方案 7:

您只需要:

@override_settings(DEBUG=True)

如果您已经有 SQL 调试语句被打印在runserver

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

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

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

感谢@Janusz Skonieczny 的回答!

解决方案 8:

如果您想要通过设置来切换此功能,请在 settings.py 中执行以下操作:

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

另请注意,只有DEBUG = True在 settings.py 中,此功能才会起作用。

感谢@Gian Marco提供的日志配置使得此功能能够正常工作。

解决方案 9:

我不知道如何将Django 中的所有 SQL 查询记录到文件中。

但是,我知道如何使用下面的代码来获取Django Admin中的SQL 查询部分。 *您还可以看到我的答案,解释如何在Django View中获取SQL 查询的部分

from django.db import connection
connection.queries

例如,您可以在adminconnection.queries中使用覆盖来获取SQL 查询save_model()如下所示:Person

# "store/admin.py"

from .models import Person
from django.db import connection

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    # Here
    def save_model(self, request, obj, form, change):
        obj.save()
        for query in connection.queries: # Here
            print(query)

然后,如果你改变一个人,如下所示:

在此处输入图片描述

SQL 查询打印在控制台上,如下所示:

{'sql': 'SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."expire_date" > \'2022-12-24T06:47:45.799803+00:00\'::timestamptz AND "django_session"."session_key" = \'7spdc2c5h3g2v5hjc898eqphf11g9eck\') LIMIT 21', 'time': '0.000'}
{'sql': 'SELECT "account_customuser"."id", "account_customuser"."password", "account_customuser"."last_login", "account_customuser"."is_superuser", "account_customuser"."first_name", "account_customuser"."last_name", "account_customuser"."is_staff", "account_customuser"."is_active", "account_customuser"."date_joined", "account_customuser"."email", "account_customuser"."phone", "account_customuser"."my_order" FROM "account_customuser" WHERE "account_customuser"."id" = 1 LIMIT 21', 'time': '0.000'}
{'sql': 'SELECT "store_person"."id", "store_person"."name" FROM "store_person" WHERE "store_person"."id" = 191 LIMIT 21', 'time': '0.000'}
{'sql': 'UPDATE "store_person" SET "name" = \'David\' WHERE "store_person"."id" = 191', 'time': '0.000'}
[24/Dec/2022 15:47:45] "POST /admin/store/person/191/change/ HTTP/1.1" 302 0
[24/Dec/2022 15:47:46] "GET /admin/store/person/ HTTP/1.1" 200 22584
[24/Dec/2022 15:47:46] "GET /admin/jsi18n/ HTTP/1.1" 200 3195

解决方案 10:

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

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用