2009-07-02 90 views

回答

256

请参阅该文档常见问题解答: “How can I see the raw SQL queries Django is running?

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

from django.db import connection 
print connection.queries 

查询集也有含query attribute查询被执行:

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

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

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

从Django bug报告#17741

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

+10

为了将来证明这个答案,你应该将当前版本的Django文档链接起来:http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw- sql-queries-django-is- – 2009-07-02 13:31:04

+18

或者只是写出答案!因为像我这样的人在寻找解决方案... – Jurudocs 2012-02-02 09:14:04

+1

查询属性?什么?在哪里 - 我检查了链接,但它是一个巨大的非字母表(为什么有人会列出不是按字母顺序排列的?)...列表... – bharal 2012-06-14 11:40:14

16

尽管您可以使用提供的代码来实现它,但我发现使用调试工具栏应用程序是显示查询的好工具。你可以从github here下载它。

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

+2

在我看来,这是最好的版本:https://github.com/django-debug-toolbar/django-debug-toolbar – philfreo 2012-01-26 21:52:20

30

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

文档和源代码可在http://django-debug-toolbar.readthedocs.io/

Screenshot of debug toolbar

+1

debug_toolbar在查询失败时出现SQL语法错误时特别有用;它将显示试图运行(并失败)的最后一个查询,使其更易于调试。 – scoopseven 2012-08-16 17:20:34

9

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

  1. django.core.context_processors.debugCONTEXT_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 %} 

我加入行

context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries]) 

在django_src/Django的/核心/ context_processors.py的调试功能得到了可变sql_time_sum。通过这个帖子

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

debug_toolbar描述settings.py

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

print q.query 
7

另一种选择,看日志选项会减慢页面加载你的dev的服务器上,记录不会那么它的速度更快。输出可以转储到控制台或文件,所以用户界面不太好。但对于含有大量SQL的视图,通过debug_toolbar调试和优化SQL可能需要很长时间,因为每个页面加载都非常缓慢。

13

没有其他的回答涵盖了这个方法,所以:

我发现迄今最有用,简单,可靠的方法就是问你的数据库。例如在Linux上Postgres的你可以这样做:

sudo su postgres 
tail -f /var/log/postgresql/postgresql-8.4-main.log 

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

22

Django-extensions有一个命令shell_plus用参数print-sql

./manage.py shell_plus --print-sql 

在Django - 壳所有执行的查询将被打印

例:

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> 
1

下面返回作为查询有效的SQL,基于https://code.djangoproject.com/ticket/17741

def str_query(qs): 
    """ 
    qs.query returns something that isn't valid SQL, this returns the actual 
    valid SQL that's executed: https://code.djangoproject.com/ticket/17741 
    """ 
    cursor = connections[qs.db].cursor() 
    query, params = qs.query.sql_with_params() 
    cursor.execute('EXPLAIN ' + query, params) 
    res = str(cursor.db.ops.last_executed_query(cursor, query, params)) 
    assert res.startswith('EXPLAIN ') 
    return res[len('EXPLAIN '):] 
0

我做了一个小片段,您可以使用:

from django.conf import settings 
from django.db import connection 


def sql_echo(method, *args, **kwargs): 
    settings.DEBUG = True 
    result = method(*args, **kwargs) 
    for query in connection.queries: 
     print(query) 
    return result 


# HOW TO USE EXAMPLE: 
# 
# result = sql_echo(my_method, 'whatever', show=True) 

它需要作为参数功能(包含SQL queryies)检查和args,调用该函数需要kwargs。结果它返回什么函数返回并在控制台中打印SQL查询。