Есть ли способ распечатать запрос, который генерирует Django ORM?
Скажем, я выполняю следующую инструкцию: Model.objects.filter(name='test')
Как мне увидеть сгенерированный SQL-запрос?
Есть ли способ распечатать запрос, который генерирует Django ORM?
Скажем, я выполняю следующую инструкцию: Model.objects.filter(name='test')
Как мне увидеть сгенерированный SQL-запрос?
Каждый объект QuerySet имеет атрибут query
, который можно регистрировать или выводить на стандартный вывод для целей отладки.
qs = Model.objects.filter(name='test')
print qs.query
Для более старых версий django попробуйте:
print str(qs.query)
Изменить
Я также использовал настраиваемые теги шаблонов (как описано в этом фрагменте) для ввода запросов в рамках одного запроса в виде HTML-комментариев.
prefetch_related
, т.е. показывает 2 запроса? Я вижу только 1.
- person user; 25.04.2014
<django.db.models.sql.query.Query object
- person dopatraman; 30.01.2019
Model.objects.create
? Я бы тоже хотел увидеть SQL для этого.
- person NeilG; 05.03.2020
print(str(qs.query))
. Большое спасибо!!!
- person theQuestionMan; 02.05.2021
Вы также можете использовать ведение журнала Python для регистрации всех запросов, сгенерированных Django. Просто добавьте это в свой файл настроек.
LOGGING = {
'disable_existing_loggers': False,
'version': 1,
'handlers': {
'console': {
# logging handler that outputs log messages to terminal
'class': 'logging.StreamHandler',
'level': 'DEBUG', # message level to be written to console
},
},
'loggers': {
'': {
# this sets root level logger to log debug and higher level
# logs to console. All other loggers inherit settings from
# root level logger.
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False, # this tells logger to send logging message
# to its parent (will send if set to True)
},
'django.db': {
# django also has database level logging
},
},
}
Другой метод в случае, если приложение генерирует вывод html - можно использовать панель инструментов отладки django.
'level': 'DEBUG'
под 'django.db'
.
- person rvernica; 18.11.2016
Вы можете вставить этот код в свою оболочку, которая будет отображать все запросы SQL:
# To get all sql queries sent by Django from py shell
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
Пока DEBUG
включен:
from django.db import connection
print(connection.queries)
По индивидуальному запросу вы можете:
print(Model.objects.filter(name='test').query)
Возможно, вам стоит взглянуть на django-debug-toolbar
приложение, оно будет регистрировать все запросы, отображать для них информацию профилирования и многое другое.
Надежным решением было бы записать журнал сервера базы данных в файл, а затем
tail -f /path/to/the/log/file.log
Если вы используете маршрутизацию базы данных, возможно, у вас несколько подключений к базе данных. Подобный код позволяет вам видеть соединения в сеансе. Вы можете сбросить статистику так же, как и при простом подключении: reset_queries()
from django.db import connections,connection,reset_queries
...
reset_queries() # resets data collection, call whenever it makes sense
...
def query_all():
for c in connections.all():
print(f"Queries per connection: Database: {c.settings_dict['NAME']} {c.queries}")
# and if you just want to count the number of queries
def query_count_all()->int:
return sum(len(c.queries) for c in connections.all() )
Вы можете использовать Django debug_toolbar для просмотра SQL-запроса. Пошаговое руководство по использованию debug_toolbar:
pip install django-debug-toolbar
Settings.py =>
INSTALLED_APPS= [ 'debug_toolbar']
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']
Settings.py => создать новый список в конце файла settings.py и добавить список ниже:
INTERNAL_IPS= [127.0.0.1']
Это позволит запускать отладку только на внутреннем сервере разработки.
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
url(r'^__debug__/', include(debug_toolbar.urls))
] + urlpatterns
Вы увидите надстройку на своей веб-странице по адресу 127.0.0.1, и если вы установите флажок SQL Query, вы также сможете увидеть время выполнения запроса.