是否有一种方法可以在执行查询时显示Django正在运行的SQL ?


当前回答

另一个选项,请参阅本文中描述的settings.py中的日志记录选项

http://dabapps.com/blog/logging-sql-queries-django-13/

Debug_toolbar会降低开发服务器上每个页面的加载速度,而日志记录则不会,因此速度更快。输出可以转储到控制台或文件,所以UI不是很好。但是对于包含大量sql的视图,通过debug_toolbar调试和优化sql可能需要很长时间,因为每个页面加载都非常慢。

其他回答

虽然可以使用提供的代码来完成,但我发现使用调试工具栏应用程序是显示查询的一个很好的工具。你可以从github下载。

这使您可以选择显示在给定页面上运行的所有查询以及查询所花费的时间。它还汇总了页面上的查询数量以及用于快速查看的总时间。当你想了解Django ORM在幕后做了什么时,这是一个很好的工具。它也有很多其他不错的功能,你可以使用,如果你喜欢。

对于Django 2.2:

当我使用。/manage.py shell时,大多数答案对我没有多大帮助。最后我找到了答案。希望这能对别人有所帮助。

查询所有查询信息。

from django.db import connection
connection.queries

查看单个查询的查询:

q=Query.objects.all()
q.query.__str__()

q。query只是为我显示对象。 使用__str__()(字符串表示)显示完整的查询。

我把这个函数放在我项目中的一个应用程序的util文件中:

import logging
import re

from django.db import connection

logger = logging.getLogger(__name__)

def sql_logger():
    logger.debug('TOTAL QUERIES: ' + str(len(connection.queries)))
    logger.debug('TOTAL TIME: ' + str(sum([float(q['time']) for q in connection.queries])))

    logger.debug('INDIVIDUAL QUERIES:')
    for i, query in enumerate(connection.queries):
        sql = re.split(r'(SELECT|FROM|WHERE|GROUP BY|ORDER BY|INNER JOIN|LIMIT)', query['sql'])
        if not sql[0]: sql = sql[1:]
        sql = [(' ' if i % 2 else '') + x for i, x in enumerate(sql)]
        logger.debug('\n### {} ({} seconds)\n\n{};\n'.format(i, query['time'], '\n'.join(sql)))

然后,当需要时,我只是导入它,并从任何上下文(通常是视图)调用它是必要的,例如:

# ... other imports
from .utils import sql_logger

class IngredientListApiView(generics.ListAPIView):
    # ... class variables and such

    # Main function that gets called when view is accessed
    def list(self, request, *args, **kwargs):
        response = super(IngredientListApiView, self).list(request, *args, **kwargs)

        # Call our function
        sql_logger()

        return response

在模板之外这样做很好,因为如果你有API视图(通常是Django Rest框架),它也适用于模板。

在django中,如果你有这样的查询:

MyModel.objects.all()

do:

MyModel.objects.all().query.sql_with_params()

or:

str(MyModel.objects.all().query)

来获取SQL字符串

请参阅文档常见问题:“如何查看Django正在运行的原始SQL查询?”

django.db.connection.queries包含一个SQL查询列表:

from django.db import connection
print(connection.queries)

queryset也有一个包含要执行的查询的query属性:

print(MyModel.objects.filter(name="my name").query)

注意,查询的输出不是有效的SQL,因为:

Django从未真正插入参数:它将查询和参数分别发送到数据库适配器,由数据库适配器执行适当的操作。

来自Django错误报告#17741。

因此,不应该将查询输出直接发送到数据库。

如果你需要重置查询,例如,查看在给定的时间内有多少查询在运行,你可以使用reset_queries from django.db:

from django.db import reset_queries
from django.db import connection

reset_queries()
# Run your query here
print(connection.queries)
>>> []