是否有一种方法可以在执行查询时显示Django正在运行的SQL ?
当前回答
从django获取查询结果到数据库(使用正确的参数替换) 你可以使用这个函数:
from django.db import connection
def print_database_query_formatted(query):
sql, params = query.sql_with_params()
cursor = connection.cursor()
cursor.execute('EXPLAIN ' + sql, params)
db_query = cursor.db.ops.last_executed_query(cursor, sql, params).replace('EXPLAIN ', '')
parts = '{}'.format(db_query).split('FROM')
print(parts[0])
if len(parts) > 1:
parts = parts[1].split('WHERE')
print('FROM{}'.format(parts[0]))
if len(parts) > 1:
parts = parts[1].split('ORDER BY')
print('WHERE{}'.format(parts[0]))
if len(parts) > 1:
print('ORDER BY{}'.format(parts[1]))
# USAGE
users = User.objects.filter(email='admin@admin.com').order_by('-id')
print_database_query_formatted(users.query)
输出示例
SELECT "users_user"."password", "users_user"."last_login", "users_user"."is_superuser", "users_user"."deleted", "users_user"."id", "users_user"."phone", "users_user"."username", "users_user"."userlastname", "users_user"."email", "users_user"."is_staff", "users_user"."is_active", "users_user"."date_joined", "users_user"."latitude", "users_user"."longitude", "users_user"."point"::bytea, "users_user"."default_search_radius", "users_user"."notifications", "users_user"."admin_theme", "users_user"."address", "users_user"."is_notify_when_buildings_in_radius", "users_user"."active_campaign_id", "users_user"."is_unsubscribed", "users_user"."sf_contact_id", "users_user"."is_agree_terms_of_service", "users_user"."is_facebook_signup", "users_user"."type_signup"
FROM "users_user"
WHERE "users_user"."email" = 'admin@admin.com'
ORDER BY "users_user"."id" DESC
它基于这个票证评论:https://code.djangoproject.com/ticket/17741#comment:4
其他回答
看一下debug_toolbar,它对调试非常有用。
文档和源代码可以在http://django-debug-toolbar.readthedocs.io/上找到。
查询实际上嵌入在模型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>
这是一个很晚的回答,但其他的都是通过搜索得到的。
我想介绍一种日志记录方法,非常简单;在settings .py中添加django.db.backends logger
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
我还使用了一个环境变量来设置级别。 所以当我想看到SQL查询时,我只是设置了环境变量,调试日志显示了实际的查询。
你可以使用连接。在Django中运行原始SQL查询,如下所示:
# "store/views.py"
from django.db import transaction
from .models import Person
from django.db import connection
from django.http import HttpResponse
@transaction.atomic
def test(request):
Person.objects.create(name="John") # INSERT
qs = Person.objects.select_for_update().get(name="John") # SELECT FOR UPDATE
qs.name = "Tom"
qs.save() # UPDATE
qs.delete() # DELETE
for query in connection.queries: # Here
print(query)
return HttpResponse("Test")
然后,原始查询打印在控制台,如下所示:
{'sql': 'INSERT INTO "store_person" ("name") VALUES (\'John\') RETURNING "store_person"."id"', 'time': '0.000'}
{'sql': 'SELECT "store_person"."id", "store_person"."name" FROM "store_person" WHERE "store_person"."name" = \'John\' LIMIT 21 FOR UPDATE', 'time': '0.000'}
{'sql': 'UPDATE "store_person" SET "name" = \'Tom\' WHERE "store_person"."id" = 179', 'time': '0.000'}
{'sql': 'DELETE FROM "store_person" WHERE "store_person"."id" IN (179)', 'time': '0.000'}
[24/Dec/2022 06:29:32] "GET /store/test/ HTTP/1.1" 200 9
然后,把reset_queries()放在Person.objects.select_for_update()之后,如果你想只得到UPDATE和DELETE查询,而没有INSERT和SELECT FOR UPDATE查询,如下所示:
# "store/views.py"
from django.db import transaction
from .models import Person
from django.db import reset_queries
from django.db import connection
from django.http import HttpResponse
@transaction.atomic
def test(request):
Person.objects.create(name="John") # INSERT
qs = Person.objects.select_for_update().get(name="John") # SELECT FOR UPDATE
reset_queries() # Here
qs.name = "Tom"
qs.save() # UPDATE
qs.delete() # DELETE
for query in connection.queries: # Here
print(query)
return HttpResponse("Test")
然后,只打印UPDATE和DELETE查询,不打印INSERT和SELECT FOR UPDATE查询,如下所示:
{'sql': 'UPDATE "store_person" SET "name" = \'Tom\' WHERE "store_person"."id" = 190', 'time': '0.000'}
{'sql': 'DELETE FROM "store_person" WHERE "store_person"."id" IN (190)', 'time': '0.000'}
[24/Dec/2022 07:00:01] "GET /store/test/ HTTP/1.1" 200 9
推荐文章
- 如何在Python中进行热编码?
- 如何嵌入HTML到IPython输出?
- 在Python生成器上使用“send”函数的目的是什么?
- 在SQL server查询中将NULL替换为0
- 在SQL中修改表的模式名
- 是否可以将已编译的.pyc文件反编译为.py文件?
- Django模型表单对象的自动创建日期
- 在Python中包装长行
- 如何计算两个时间串之间的时间间隔
- 如何在SQL Server 2005的一条语句中更新两个表?
- 我如何才能找到一个Python函数的参数的数量?
- 您可以使用生成器函数来做什么?
- 将Python诗歌与Docker集成
- 提取和保存视频帧
- 使用请求包时出现SSL InsecurePlatform错误