使用优秀的Django-Devserver我在我的代码中找到各种有趣和意外的SQL调用。我想找到调用的来源,所以我正在寻找一种方法来获取日志或打印出在Python shell中由Django ORM生成的所有SQL调用。也就是说,当我通过Python shell进行Django ORM调用时,我希望看到打印出来或记录生成的SQL。
我注意到几个将日志信息添加到html页面的解决方案。是否有一种简单的方法转储到命令行?
答案 0 :(得分:180)
如果您使用的是Django 1.3:
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
答案 1 :(得分:29)
Rob Hudson的Django Debug Toolbar,以及它的一般性的awesomness,还包括一个非常漂亮的debugsqlshell
manage.py命令,它正是这样做的。
答案 2 :(得分:25)
我试图在生产服务器上的shell中使用“Django: show/log ORM sql calls from python 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())
我要离开这里,所以我可以在以后找到它,并希望它可以节省其他人同样的挖掘工作。
答案 3 :(得分:18)
使用django扩展程序。
pip install django-extensions
./manage.py shell_plus --print-sql
对于生产环境,由于调试设置,它可能无法正常工作。
答案 4 :(得分:11)
如果你在shell中,或者在任何地方,你可以使用queryset方法
query.as_sql()
打印SQL命令。
即:
MyModel.objects.all().query.as_sql()
答案 5 :(得分:6)
qs = YourModel.objects.all()
qs.query.get_compiler('default').as_sql()
答案 6 :(得分:5)
如果您真的想要查看/记录所有SQL查询,那么您将需要尝试使用Django 1.3(目前处于alpha版本,但很快就会投入生产),这样可以为许多组件启用Python loggers,包括数据库后端。
当然,如果你使用稳定版本的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 )
到此:
{{1}}
答案 7 :(得分:0)
顺便提一下另一个选项 - 我制作了 django-sql-sniffer
工具,以便它可以附加到任何正在运行的 Python 进程并监视/分析来自 Django ORM 的 SQL 执行。
因此,它还可用于监控来自 Python shell 进程的查询(请参阅演示视频的 github 页):
In [1]: import os
In [2]: os.getpid()
Out[2]: 99688
django-sql-sniffer
(在本例中指定尾模式以实时跟踪查询)$ 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
-------------------------------------------------------
Ctrl + C
停止该工具并分析所有捕获的查询=======================================================
____ ___ _ ____ _____ _ _____ ____
/ ___| / _ \ | | / ___||_ _| / \ |_ _|/ ___|
\___ \ | | | || | \___ \ | | / _ \ | | \___ \
___) || |_| || |___ ___) | | | / ___ \ | | ___) |
|____/ \__\_\|_____| |____/ |_|/_/ \_\|_| |____/
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"
-------------------------------------------------------
=======================================================