请查看文档中的常见问题解答: "如何查看 Django 正在运行的原始 SQL 查询?"
django.db.connection.queries
包含了 SQL 查询的列表:
from django.db import connection
print(connection.queries)
查询集还有一个query
属性,其中包含要执行的查询:
print(MyModel.objects.filter(name="my name").query)
请注意,查询的输出不是有效的SQL,因为:
"Django实际上从不插入参数:它将查询和参数分别发送到数据库适配器中,然后执行相应的操作。"
来自Django错误报告#17741。
因此,您不应直接将查询输出发送到数据库。
如果您需要重置查询,例如查看在给定时间段内有多少个查询正在运行,可以使用django.db
中的reset_queries
:
from django.db import reset_queries
from django.db import connection
reset_queries()
# Run your query here
print(connection.queries)
>>> []
str()
函数,它调用内部的__str __()
方法。例如:str(MyModel.objects.filter(name="my name").query)
我还建议使用IPython和你项目中的Django shell。通过制表符完成可以提供对象内省。由于Django以自己的规范命名而著称,所以这种方法通常非常有用。 - Lorenz Lo Sauerquery
的输出结果并不是有效的SQL语句,因为“Django从未实际插值参数:它会将查询和参数分别发送到数据库适配器中,后者会执行适当的操作。”来源:https://code.djangoproject.com/ticket/17741 - gregoltsovstable
而不是 dev
来链接到 Django 的当前版本,像这样:https://docs.djangoproject.com/en/stable/faq/models/#how-can-i-see-the-raw-sql-queries-django-is-running - FlimmDjango-extensions有一个命令shell_plus,其中包含一个print-sql
参数。
./manage.py shell_plus --print-sql
在 Django Shell 中,所有执行的查询都将被打印出来。User.objects.get(pk=1)
SELECT "auth_user"."id",
"auth_user"."password",
"auth_user"."last_login",
"auth_user"."is_superuser",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 1
Execution time: 0.002466s [Database: default]
<User: username>
查询实际上是嵌入在模型 API 中的:
q = Query.objects.values('val1','val2','val_etc')
print(q.query)
m = MyModel.objects.get(...)
然后执行 m.query
时它不起作用。 - s gm
不再是一个queryset了。使用q=MyModel.objects.filter(...)
,然后q.query
,然后m=q.get()
。 - Brouwer没有其他答案涵盖了这种方法,所以:
我发现迄今为止最有用、简单和可靠的方法是向您的数据库询问。例如,在Linux上使用Postgres,您可以这样做:
sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log
每个数据库的过程略有不同。在数据库日志中,您不仅可以看到原始 SQL,还可以看到 Django 在系统上放置的任何连接设置或事务开销。
postgresql.conf
中设置 log_statement='all'
以使用这种方法。 - RickyApsql -U postgres -c 'SHOW config_file'
来查找您的 postgresql.conf
文件。 - kramer65django.db.backends
记录器。LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
我也使用一个环境变量来设置日志级别。因此,当我想查看SQL查询时,只需设置环境变量,调试日志将显示实际的查询语句。
另一个选择是,在设置文件settings.py中查看此帖子描述的日志选项。
http://dabapps.com/blog/logging-sql-queries-django-13/
debug_toolbar会减缓开发服务器上每个页面的加载速度,而日志不会,所以它更快。输出可以转储到控制台或文件中,因此UI不如debug_toolbar那样好看。但对于具有大量SQL的视图,通过debug_toolbar调试和优化SQL可能需要很长时间,因为每个页面的加载速度都非常慢。
pip install django-print-sql
from django_print_sql import print_sql
# Set `count_only` to `True` will print the number of executed SQL statements only
with print_sql(count_only=False):
# Write the code you want to analyze in here,
# e.g., some complex foreign key lookup,
# or analyzing a DRF serializer's performance
for user in User.objects.all()[:10]:
user.groups.first()
from django_print_sql import print_sql_decorator
@print_sql_decorator(count_only=False) # This works on class-based views as well
def get(request):
# Your view code here
django.core.context_processors.debug
列在CONTEXT_PROCESSORS
中DEBUG=True
IP
在INTERNAL_IPS
元组中sql_queries
变量。我会在每个页面附加一个类似于以下内容的页脚:{%if sql_queries %}
<div class="footNav">
<h2>Queries</h2>
<p>
{{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}, {{sql_time_sum}} Time
{% ifnotequal sql_queries|length 0 %}
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.disp\
lay=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
{% endifnotequal %}
</p>
<table id="debugQueryTable" style="display: none;">
<col width="1"></col>
<col></col>
<col width="1"></col>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">SQL</th>
<th scope="col">Time</th>
</tr>
</thead>
<tbody>
{% for query in sql_queries %}
<tr class="{% cycle odd,even %}">
<td>{{ forloop.counter }}</td>
<td>{{ query.sql|escape }}</td>
<td>{{ query.time }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
我通过添加以下代码行得到变量sql_time_sum
:
context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])
到django_src/django/core/context_processors.py中的debug函数。