是否有一种方法可以在执行查询时显示Django正在运行的SQL ?
当前回答
我为此开发了一个扩展,所以你可以很容易地在你的视图函数上放一个装饰器,看看有多少查询被执行了。
如何安装:
$ pip install django-print-sql
用作上下文管理器:
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()
装饰:用作装饰:
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
Github: https://github.com/rabbit-aaron/django-print-sql
其他回答
我把这个函数放在我项目中的一个应用程序的util文件中:
import logging
import re
from django.db import connection
logger = logging.getLogger(__name__)
def sql_logger():
logger.debug('TOTAL QUERIES: ' + str(len(connection.queries)))
logger.debug('TOTAL TIME: ' + str(sum([float(q['time']) for q in connection.queries])))
logger.debug('INDIVIDUAL QUERIES:')
for i, query in enumerate(connection.queries):
sql = re.split(r'(SELECT|FROM|WHERE|GROUP BY|ORDER BY|INNER JOIN|LIMIT)', query['sql'])
if not sql[0]: sql = sql[1:]
sql = [(' ' if i % 2 else '') + x for i, x in enumerate(sql)]
logger.debug('\n### {} ({} seconds)\n\n{};\n'.format(i, query['time'], '\n'.join(sql)))
然后,当需要时,我只是导入它,并从任何上下文(通常是视图)调用它是必要的,例如:
# ... other imports
from .utils import sql_logger
class IngredientListApiView(generics.ListAPIView):
# ... class variables and such
# Main function that gets called when view is accessed
def list(self, request, *args, **kwargs):
response = super(IngredientListApiView, self).list(request, *args, **kwargs)
# Call our function
sql_logger()
return response
在模板之外这样做很好,因为如果你有API视图(通常是Django Rest框架),它也适用于模板。
查询实际上嵌入在模型API中:
q = Query.objects.values('val1','val2','val_etc')
print(q.query)
django扩展有一个带参数print-sql的命令shell_plus
./manage.py shell_plus --print-sql
在django-shell中,所有执行的查询都会被打印出来
Ex.:
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>
使用django.db.connection.queries查看查询
from django.db import connection
print(connection.queries)
访问QuerySet对象上的原始SQL查询
qs = MyModel.objects.all()
print(qs.query)
我已经做了一个你可以使用的小片段:
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查询)来检查和args, kwargs需要调用该函数。结果它返回函数返回的内容,并在控制台中打印SQL查询。
推荐文章
- 数据类vs类型。NamedTuple主要用例
- 如何从macOS完全卸载蟒蛇
- 是否有可能键入提示一个lambda函数?
- 'dict'对象没有has_key属性
- 使用Pandas groupby连接来自几行的字符串
- Pandas:给定列的数据帧行之和
- 如何避免在为Python项目构建Docker映像时重新安装包?
- 如何激活蟒蛇环境
- 省略[…]意思是在一个列表里?
- 在SQL Server 2008 R2中重命名数据库时出错
- 将数据复制到另一个表中
- 将表从一个数据库复制到另一个数据库的最简单方法?
- 为什么我得到“'str'对象没有属性'读取'”当尝试使用' json。载入字符串?
- 不区分大小写的列表排序,没有降低结果?
- 排序后的语法(key=lambda:…)