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


当前回答

查询实际上嵌入在模型API中:

q = Query.objects.values('val1','val2','val_etc')

print(q.query)

其他回答

对于Django 2.2:

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

查询所有查询信息。

from django.db import connection
connection.queries

查看单个查询的查询:

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

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

请参阅文档常见问题:“如何查看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)
>>> []

如果你确保你的settings.py文件有:

django.core.context_processors.debug中列出的 DEBUG = True INTERNAL_IPS元组中的IP

然后您应该可以访问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函数。

Django SQL Sniffer是查看(和查看)从Django ORM的任何进程中执行的原始查询的另一种选择。我已经构建了它来满足我所拥有的一个特定用例,我在任何地方都没有看到过,即:

不需要更改目标进程正在执行的源代码(不需要在django设置中注册一个新的应用程序,到处导入装饰器等)。 不更改日志配置(例如,因为我对一个特定的进程感兴趣,而不是配置应用的整个进程群) 不需要重新启动目标进程(例如,因为它是一个重要的组件,重新启动可能会导致一些停机时间)

因此,Django SQL Sniffer可以特别使用,并附加到已经运行的进程。然后,该工具“嗅探”已执行的查询,并在执行时将它们打印到控制台。当工具停止时,将显示一个统计摘要,其中包含基于某些可能的度量(计数、最大持续时间和总组合持续时间)的异常值查询。

这是我附加到Python shell的示例的截图

你可以在github页面上查看现场演示和更多细节。

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

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