Django:show/log来自python shell的ORMSQL调用

Django:show/log来自python shell的ORMSQL调用,django,orm,Django,Orm,使用优秀的SQL语句,我在代码中发现了各种有趣和意外的SQL调用。我想找到调用来自何处,因此我正在寻找一种方法来获取Python shell中Django ORM生成的所有SQL调用的日志或打印输出。也就是说,当我通过pythonshell执行Django-ORM调用时,我希望看到结果SQL打印出来或记录下来 我注意到有几种将日志信息添加到html页面的解决方案。是否有一种简单的方法可以将其转储到命令行?Rob Hudson's以及它的一般功能,还包括一个非常漂亮的debugsqlshellma

使用优秀的SQL语句,我在代码中发现了各种有趣和意外的SQL调用。我想找到调用来自何处,因此我正在寻找一种方法来获取Python shell中Django ORM生成的所有SQL调用的日志或打印输出。也就是说,当我通过pythonshell执行Django-ORM调用时,我希望看到结果SQL打印出来或记录下来


我注意到有几种将日志信息添加到html页面的解决方案。是否有一种简单的方法可以将其转储到命令行?

Rob Hudson's以及它的一般功能,还包括一个非常漂亮的
debugsqlshell
manage.py命令,它可以实现这一点。

如果您在shell中,或者在任何地方,您都可以使用queryset方法

query.as_sql()
打印SQL命令

即:


如果您真的很想查看/记录所有SQL查询,那么您应该尝试Django 1.3(目前在alpha中,但即将投入生产),它支持许多组件,包括数据库后端

当然,如果您一直在使用Django的稳定版本,您可以通过将以下内容添加到导入列表的底部来修补
Django/db/models/sql/compiler.py
,相对轻松地获得相同的效果:

import logging
_querylogger = logging.getLogger( 'sql.compiler' )
查找
SQLCompiler::execute_sql()
方法并更改:

    cursor = self.connection.cursor()
    cursor.execute( sql, params )
为此:

    cursor = self.connection.cursor()
    _querylogger.info( "%s <= %s", sql, params )
    cursor.execute( sql, params )
cursor=self.connection.cursor()

_querylogger.info(“%s如果您使用的是Django 1.3:

import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
我试图在生产服务器上的shell中使用“”,但它不起作用。最终有人指出,它只会在
debug=True
时进行此调试日志记录。但您可以这样解决此问题:

import logging
from django.db import connection
connection.force_debug_cursor = True  # Change to use_debug_cursor in django < 1.8
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
导入日志
从django.db导入连接
connection.force_debug_cursor=True#更改为在django中使用_debug_cursor<1.8
l=logging.getLogger('django.db.backends'))
l、 setLevel(logging.DEBUG)
l、 addHandler(logging.StreamHandler())
我把这个放在这里,以便以后能找到它,希望它能像我一样为其他人节省时间。

使用django扩展

pip install django-extensions
./manage.py shell_plus --print-sql

对于生产环境,由于调试设置,它可能无法工作。

仅提及另一个选项-我制作了
django sql sniffer
工具,以便它可以连接到任何正在运行的Python进程,并监视/分析来自django ORM的sql执行

因此,它还可以用于监视来自Python shell进程的查询(请参见第页的演示视频):

  • 打开shell并获取进程ID:
  • 在另一个选项卡中附加
    django sql sniffer
    (在本例中,指定跟踪实时查询的尾部模式)
  • 返回shell并开始执行查询
  • 该工具在执行原始查询时打印这些查询
  • 最后,点击
    Ctrl+C
    停止该工具并对所有捕获的查询进行分析

您还可以执行>>>打印MyModel.objects.all()。查询使用Django 1.5和
query.as_sql()
对我不起作用。
query.sql\u with_params()
则起作用。在幕后查找调用的来源和进行的操作“我还建议使用Django Debug Toolbar。不仅适用于debugsqlshell命令,也适用于实际的工具栏,其中还包含大量有关SQL调用的信息。str(qs)工作也很好。如果我使用django 1.2呢?+1这也适用于django 1.5,你一辈子都在哪里?这对django 1.8仍然很有用。ruby on rails控制台默认启用了这种输出,我希望复制这种输出;太好了!我应该把这段代码放在settings.py?Noob中吗?请帮助。即使在在生产环境中,您可以运行
settings.DEBUG=True
作为第一个Python shell_plus命令。如果Django生成的查询太长(这很可能是因为您的表只有几列),则shell将停止打印并继续执行。我看到的任何查询都不会到达WHERE子句。
import logging
from django.db import connection
connection.force_debug_cursor = True  # Change to use_debug_cursor in django < 1.8
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
pip install django-extensions
./manage.py shell_plus --print-sql
In [1]: import os

In [2]: os.getpid()
Out[2]: 99688
$ django-sql-sniffer -p 99688 -t
In [3]: cat library/models.py
from django.db import models


class Book(models.Model):
    title = models.CharField(null=False, blank=False, max_length=100)
    author = models.ForeignKey('Author', on_delete=models.CASCADE)


class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)


In [4]: from library.models import *

In [5]: books = Book.objects.all()

In [6]: len(books)  # better use count
Out[6]: 121000

In [7]: book = books.first()  # query set not ordered, will hit db again

In [8]: book = books.first()  # query set not ordered, will hit db again

In [9]: book = books.first()  # query set not ordered, will hit db again

In [10]: book.author.id  # better use author_id
Out[10]: 1

In [11]: Book.objects.filter(author__first_name__startswith='A').count() > 0
Out[11]: True

In [12]: Book.objects.filter(author__first_name__startswith='A').exists()
Out[12]: True
Count: 1; Duration: 0.002211809; Max Duration: 0.002211809; Query:
SELECT "library_book"."id",
       "library_book"."title",
       "library_book"."author_id"
  FROM "library_book"
-------------------------------------------------------
Count: 1; Duration: 0.000240326; Max Duration: 0.000240326; Query:
SELECT "library_book"."id",
       "library_book"."title",
       "library_book"."author_id"
  FROM "library_book"
 ORDER BY "library_book"."id" ASC
 LIMIT 1
-------------------------------------------------------
Count: 2; Duration: 0.000150919; Max Duration: 0.000240326; Query:
SELECT "library_book"."id",
       "library_book"."title",
       "library_book"."author_id"
  FROM "library_book"
 ORDER BY "library_book"."id" ASC
 LIMIT 1
-------------------------------------------------------
Count: 3; Duration: 0.000187874; Max Duration: 0.000240326; Query:
SELECT "library_book"."id",
       "library_book"."title",
       "library_book"."author_id"
  FROM "library_book"
 ORDER BY "library_book"."id" ASC
 LIMIT 1
-------------------------------------------------------
Count: 1; Duration: 0.000919104; Max Duration: 0.000919104; Query:
SELECT "library_author"."id",
       "library_author"."first_name",
       "library_author"."last_name"
  FROM "library_author"
 WHERE "library_author"."id" = %s
 LIMIT 21
-------------------------------------------------------
Count: 1; Duration: 0.040677071; Max Duration: 0.040677071; Query:
SELECT COUNT(*) AS "__count"
  FROM "library_book"
 INNER JOIN "library_author"
    ON ("library_book"."author_id" = "library_author"."id")
 WHERE "library_author"."first_name" LIKE %s ESCAPE '\'
-------------------------------------------------------
Count: 1; Duration: 0.002345800; Max Duration: 0.002345800; Query:
SELECT (1) AS "a"
  FROM "library_book"
 INNER JOIN "library_author"
    ON ("library_book"."author_id" = "library_author"."id")
 WHERE "library_author"."first_name" LIKE %s ESCAPE '\'
 LIMIT 1
-------------------------------------------------------
=======================================================

  ____    ___   _       ____  _____   _   _____  ____
 / ___|  / _ \ | |     / ___||_   _| / \ |_   _|/ ___|
 \___ \ | | | || |     \___ \  | |  / _ \  | |  \___ \
  ___) || |_| || |___   ___) | | | / ___ \ | |   ___) |
 |____/  \__\_\|_____| |____/  |_|/_/   \_\|_|  |____/

               Django SQL Sniffer v1.0.0
=======================================================
             TOP QUERIES BY MAX DURATION


Count: 1; Max Duration: 0.040677071; Combined Duration: 0.040677071; Query:
SELECT COUNT(*) AS "__count"
  FROM "library_book"
 INNER JOIN "library_author"
    ON ("library_book"."author_id" = "library_author"."id")
 WHERE "library_author"."first_name" LIKE %s ESCAPE '\'
-------------------------------------------------------
Count: 1; Max Duration: 0.002345800; Combined Duration: 0.002345800; Query:
SELECT (1) AS "a"
  FROM "library_book"
 INNER JOIN "library_author"
    ON ("library_book"."author_id" = "library_author"."id")
 WHERE "library_author"."first_name" LIKE %s ESCAPE '\'
 LIMIT 1
-------------------------------------------------------
Count: 1; Max Duration: 0.002211809; Combined Duration: 0.002211809; Query:
SELECT "library_book"."id",
       "library_book"."title",
       "library_book"."author_id"
  FROM "library_book"
-------------------------------------------------------
=======================================================