Как просмотреть соответствующий SQL-запрос набора запросов Django ORM?

Есть ли способ распечатать запрос, который генерирует Django ORM?

Скажем, я выполняю следующую инструкцию: Model.objects.filter(name='test')

Как мне увидеть сгенерированный SQL-запрос?


person Community    schedule 09.06.2009    source источник


Ответы (8)


Каждый объект QuerySet имеет атрибут query, который можно регистрировать или выводить на стандартный вывод для целей отладки.

qs = Model.objects.filter(name='test')
print qs.query

Для более старых версий django попробуйте:

print str(qs.query)

Изменить

Я также использовал настраиваемые теги шаблонов (как описано в этом фрагменте) для ввода запросов в рамках одного запроса в виде HTML-комментариев.

person Joe Holloway    schedule 09.06.2009
comment
как насчет запросов для .save ()? - person DataGreed; 25.08.2010
comment
@DataGreed Хороший вопрос, возможно, стоит задать ему новую тему, чтобы получить больше ответов. - person Joe Holloway; 27.08.2010
comment
Работает ли он с prefetch_related, т.е. показывает 2 запроса? Я вижу только 1. - person user; 25.04.2014
comment
не работает. я вижу <django.db.models.sql.query.Query object - person dopatraman; 30.01.2019
comment
Попробуйте print (str (qs.query)). Я думаю, они немного изменили внутреннее устройство за 10 лет - person Joe Holloway; 01.02.2019
comment
А что насчет Model.objects.create? Я бы тоже хотел увидеть SQL для этого. - person NeilG; 05.03.2020
comment
@JoeHolloway, ты спас день своим комментарием к 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.

person aisbaa    schedule 07.07.2012
comment
Если кто-то хочет получить сводку с суммой количества выполненных запросов, а также общее время, потребовалось: dabapps.com/blog/logging-sql-queries-django-13 - person andilabs; 13.05.2015
comment
У меня не вышло, пришлось добавить '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())
person Pramod    schedule 28.10.2012

Пока DEBUG включен:

from django.db import connection
print(connection.queries)

По индивидуальному запросу вы можете:

print(Model.objects.filter(name='test').query)
person Daniel Roseman    schedule 09.06.2009

Возможно, вам стоит взглянуть на django-debug-toolbar приложение, оно будет регистрировать все запросы, отображать для них информацию профилирования и многое другое.

person Mikhail Korobov    schedule 09.06.2009
comment
Это очень полезно, но работает только в графическом интерфейсе, и иногда вы хотите видеть журналы запросов прямо в ORM. например у вас есть API без графического интерфейса! - person wim; 27.09.2016

Надежным решением было бы записать журнал сервера базы данных в файл, а затем

tail -f /path/to/the/log/file.log
person alan    schedule 20.02.2014

Если вы используете маршрутизацию базы данных, возможно, у вас несколько подключений к базе данных. Подобный код позволяет вам видеть соединения в сеансе. Вы можете сбросить статистику так же, как и при простом подключении: 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() )
person Tim Richardson    schedule 01.12.2019

Вы можете использовать Django debug_toolbar для просмотра SQL-запроса. Пошаговое руководство по использованию debug_toolbar:

Установите Debug_toolbar

pip install django-debug-toolbar

Отредактируйте файл settings.py и добавьте debug_toolbar в Установленные приложения, это должно быть добавлено ниже в django.contrib.staticfiles. Также добавьте debug_toolbar в промежуточное ПО.

Settings.py =>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

создать новый список с именем INTERNAL_IPS в файле settings.py

Settings.py => создать новый список в конце файла settings.py и добавить список ниже:

INTERNAL_IPS= [127.0.0.1']

Это позволит запускать отладку только на внутреннем сервере разработки.

Отредактируйте файл urls.py #Project и добавьте ниже код:

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
    url(r'^__debug__/', include(debug_toolbar.urls))       
    ] + urlpatterns

применить миграцию и снова запустить сервер

Вы увидите надстройку на своей веб-странице по адресу 127.0.0.1, и если вы установите флажок SQL Query, вы также сможете увидеть время выполнения запроса.

person Devesh G    schedule 05.12.2017