如何查看Django ORM查询集的相应SQL查询?

197

有没有一种方法可以打印出Django ORM所生成的查询语句?

例如,我执行以下语句:Model.objects.filter(name='test')

我该如何查看生成的SQL查询语句呢?

8个回答

230
每个QuerySet对象都有一个query属性,你可以记录或打印到标准输出(stdout)进行调试。
qs = Model.objects.filter(name='test')
print(qs.query)

注意,在pdb中,使用p qs.query将不能按预期工作,但print(qs.query)将可以。

如果这不起作用,对于旧版本的Django,请尝试:

print str(qs.query)

编辑

我还使用了自定义模板标签(如此片段中所述),将查询作为HTML注释注入到单个请求的范围内。


7
.save()方法的查询怎么样? - DataGreed
5
它是否适用于prefetch_related,即显示2个查询?我只看到1个。 - user
1
尝试打印(str(qs.query))。我认为他们在10年内改变了内部结构。 - Joe Holloway
@JoeHolloway,你的print(str(qs.query))评论解决了我的问题。非常感谢你! - theQuestionMan
在pdb中,只需使用str(qs.query)即可非常简单地工作。 - Doha Simon
显示剩余5条评论

127

你还可以使用 Python 日志记录器 (logging) 来记录 Django 生成的所有查询。只需将以下代码添加到你的设置文件中即可。

LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'handlers': {
        'console': {
            # logging handler that outputs log messages to terminal
            'class': 'logging.StreamHandler',
            'level': 'DEBUG', # message level to be written to console
        },
    },
    'loggers': {
        '': {
            # this sets root level logger to log debug and higher level
            # logs to console. All other loggers inherit settings from
            # root level logger.
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False, # this tells logger to send logging message
                                # to its parent (will send if set to True)
        },
        'django.db': {
            # django also has database level logging
            'level': 'DEBUG'
        },
    },
}

如果应用程序生成HTML输出,可以使用Django Debug Toolbar进行调试。


3
如果有人想要使用Sumup生成已执行查询次数总时间的摘要:请查看http://www.dabapps.com/blog/logging-sql-queries-django-13/。 - andilabs
11
对我来说没有用,我不得不在 'django.db' 下面添加 'level': 'DEBUG' - rvernica

116

您可以将以下代码粘贴到Django shell中,这将显示所有的SQL查询:

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

80
只要 DEBUG 开启:
from django.db import connection
print(connection.queries)

对于单个查询,您可以执行以下操作:

print(Model.objects.filter(name='test').query)

29

也许你应该看看 django-debug-toolbar 应用程序,它可以为你记录所有查询,并显示它们的性能信息等更多内容。


4
这非常有用,但它只适用于图形用户界面,有时您希望直接在ORM中查看查询日志。例如,您有一个没有GUI的API! - wim

2

一种健壮的解决方案是让您的数据库服务器记录到一个文件中,然后

tail -f /path/to/the/log/file.log

1
如果您正在使用数据库路由,那么您可能有多个数据库连接。像这样的代码可以让您在会话中查看连接。您可以通过与单个连接相同的方式重置统计信息:reset_queries()
from django.db import connections,connection,reset_queries
...
reset_queries()  # resets data collection, call whenever it makes sense

...

def query_all():
    for c in connections.all():
        print(f"Queries per connection: Database: {c.settings_dict['NAME']} {c.queries}")

# and if you just want to count the number of queries
def query_count_all()->int:
    return sum(len(c.queries) for c in connections.all() )

-1

您可以使用Django debug_toolbar查看SQL查询。 使用debug_toolbar的逐步指南:

安装Debug_toolbar

pip install django-debug-toolbar

编辑settings.py文件并将debug_toolbar添加到Installed apps中,应该在'django.contrib.staticfiles'下面添加。同时将debug_toolbar添加到Middleware中。

Settings.py=>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

在settings.py文件中创建一个名为INTERNAL_IPS的新列表

在settings.py文件的末尾创建一个新列表,并添加以下内容:

INTERNAL_IPS= [127.0.0.1']

这将允许调试仅在内部开发服务器上运行

编辑#Project的urls.py文件并添加以下代码:

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
    url(r'^__debug__/', include(debug_toolbar.urls))       
    ] + urlpatterns

应用迁移并重新运行服务器

您将在127.0.0.1的网页上看到一个插件,如果您勾选SQL查询复选框,您实际上可以看到查询的运行时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接