如何查看Django正在运行的原始SQL查询?

spe*_*e91 272 sql django

有没有办法在执行查询时显示Django正在运行的SQL?

geo*_*wa4 338

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

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

from django.db import connection
print(connection.queries)
Run Code Online (Sandbox Code Playgroud)

查询集还有一个包含要执行的查询的query属性:

print(MyModel.objects.filter(name="my name").query)
Run Code Online (Sandbox Code Playgroud)

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

"Django从未实际插入参数:它将查询和参数分别发送到数据库适配器,后者执行适当的操作."

来自Django的错误报告#17741.

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

  • 或者只是写下答案!因为像我这样的人在寻找解决方案...... (21认同)
  • 为了将来证明这个答案你应该链接当前版本的Django文档:http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw-sql-queries -django-是运行的 (11认同)
  • 请注意,`query`的输出不是有效的SQL,因为"Django实际上从不插入参数:它将查询和参数分别发送到数据库适配器,后者执行适当的操作." 资料来源:https://code.djangoproject.com/ticket/17741 (7认同)
  • 很好的答案.但是,建议使用指定的内置Pythonian`str()`函数,该函数调用内部`__str __()`方法.例如`str(MyModel.objects.filter(name ="my name").query)`我还建议你使用项目的IPython和Django shell.Tab完成然后提供对象内省.由于Django以其自信的命名方案而闻名,因此这种方法非常有用. (4认同)
  • @AndreMiller 您应该使用 `stable` 而不是 `dev` 来链接到当前版本的 Django,如下所示:https://docs.djangoproject.com/en/stable/faq/models/#how-can-i -see-the-raw-sql-queries-django-is-running (4认同)
  • django.db.connection.queries 返回空列表 (3认同)
  • 请注意,DEBUG 设置必须设置为 trueish,connection.queries 才能在其中包含任何内容,如链接到答案的 Django 文档中所述:“确保您的 Django DEBUG 设置设置为 True”。 (2认同)

小智 49

Django-extensions有一个带参数的命令shell_plusprint-sql

./manage.py shell_plus --print-sql
Run Code Online (Sandbox Code Playgroud)

在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>
Run Code Online (Sandbox Code Playgroud)

  • 您需要在 settings.py 中设置 DEBUG = True 才能查看查询 (2认同)

小智 48

看看debug_toolbar,它对调试非常有用.

有关文档和来源的信息,请访问http://django-debug-toolbar.readthedocs.io/.

调试工具栏的屏幕截图

  • 当您的查询因 SQL 语法错误而失败时,debug_toolbar 尤其有用;它将显示尝试运行(但失败)的最后一个查询,从而更易于调试。 (2认同)

cli*_*oog 22

这是一个迟来的答案。但其他人是为了谁才来到这里的。

我想介绍一种日志记录方法,很简单;django.db.backends在settings.py中添加记录器

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}
Run Code Online (Sandbox Code Playgroud)

我还使用环境变量来设置级别。因此,当我想查看 SQL 查询时,我只需设置环境变量,调试日志就会显示实际的查询。


Bry*_*yce 21

没有其他答案涵盖此方法,因此:

我发现到目前为止最有用,最简单,最可靠的方法是询问你的数据库.例如,在Linux for Postgres上你可能会这样做:

sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log
Run Code Online (Sandbox Code Playgroud)

每个数据库的程序都略有不同.在数据库日志中,您不仅会看到原始SQL,还会看到django放置在系统上的任何连接设置或事务开销.

  • 不要忘记在`postgresql.conf`中为此方法设置`log_statement ='all'`. (6认同)
  • 您可以通过运行“psql -U postgres -c 'SHOW config_file'”找到您的“postgresql.conf” (2认同)

小智 19

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

print q.query
Run Code Online (Sandbox Code Playgroud)

  • 或者`str(q.query)` (3认同)
  • 那是因为 `m` 不再是一个查询集。使用“q = MyModel.objects.filter(...)”,然后使用“q.query”,然后使用“m = q.get()”。 (2认同)

goo*_*orp 17

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

这使您可以选择显示在给定页面上运行的所有查询以及查询所花费的时间.它还总结了页面上的查询数量以及快速审核的总时间.当你想看看Django ORM在幕后做什么时,这是一个很棒的工具.它还有许多其他很好的功能,如果你愿意,你可以使用它们.

  • 在我看来这是最好的版本:https://github.com/django-debug-toolbar/django-debug-toolbar (2认同)

Ove*_*ked 15

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

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

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


Mik*_*den 10

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

  1. django.core.context_processors.debug 列于 CONTEXT_PROCESSORS
  2. DEBUG=True
  3. IPINTERNAL_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 %}
Run Code Online (Sandbox Code Playgroud)

sql_time_sum通过添加行来获得变量

context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])
Run Code Online (Sandbox Code Playgroud)

到django_src/django/core/context_processors.py中的debug函数.


mgp*_*hys 9

Django SQL Sniffer 是查看(并查看统计数据)来自使用 Django ORM 的任何进程的原始执行查询的另一种选择。我构建它是为了满足我所拥有的特定用例,但我在任何地方都没有看到该用例,即:

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

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

这是我附加到 Python shell 的示例的屏幕截图 在此输入图像描述

您可以在github 页面上查看现场演示和更多详细信息。


rab*_*ron 8

我为此开发了一个扩展,因此您可以轻松地在视图函数上放置一个装饰器,并查看执行了多少查询.

安装:

$ pip install django-print-sql
Run Code Online (Sandbox Code Playgroud)

要用作上下文管理器:

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()
Run Code Online (Sandbox Code Playgroud)

要用作装饰器:

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
Run Code Online (Sandbox Code Playgroud)

Github:https://github.com/rabbit-aaron/django-print-sql


rob*_*ace 6

只是补充一下,在 Django 中,如果您有以下查询:

MyModel.objects.all()
Run Code Online (Sandbox Code Playgroud)

做:

MyModel.objects.all().query.sql_with_params()
Run Code Online (Sandbox Code Playgroud)

或者:

str(MyModel.objects.all().query)
Run Code Online (Sandbox Code Playgroud)

获取sql字符串