Как я могу увидеть необработанные SQL-запросы, которые выполняет Django?

Есть ли способ показать SQL, который работает Django при выполнении запроса?

Ответы на вопрос(13)

я считаю, что использование приложения панели инструментов отладки является отличным инструментом для отображения запросов. Вы можете скачать его с GitHubВот.

Это дает вам возможность показать все запросы, выполненные на данной странице, а также время, затраченное на запрос. Он также суммирует количество запросов на странице вместе с общим временем для быстрого просмотра. Это отличный инструмент, когда вы хотите посмотреть на то, что Django ORM делает за кулисами. Он также имеет много других приятных функций, которые вы можете использовать, если хотите.

 26 янв. 2012 г., 22:52
Похоже, это лучшая версия:github.com/d,jango-debug-toolbar/django-debug-toolbar

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-запросы) для проверки и аргументов, kwargs, необходимых для вызова этой функции. В результате он возвращает то, что возвращает функция, и печатает SQL-запросы в консоли.

Django-расширение есть командаshell_plus с параметромprint-sql

..py shell_plus --print-sql

В django-shell все выполненные запросы будут напечатаны

Напр .:

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>
 16 мая 2017 г., 11:43
Я использую его с --print-sql или с SHELL_PLUS_PRINT_SQL = True, и это не помогает - я все еще не вижу запросы. есть идеи почему? Джанго 1,8

django.core.context_processors.debug listed in CONTEXT_PROCESSORS DEBUG=True your IP in the INTERNAL_IPS tuple

Тогда вы должны иметь доступ кsql_queries переменная. Я добавляю нижний колонтитул к каждой странице, которая выглядит следующим образом:

{%if sql_queries %}
  <div class="footNav">
    <h2>Queries</h2>
    <p>
      {{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}, {{sql_time_sum}} Time
    {% ifnotequal sql_queries|length 0 %}
      (<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.disp\
lay=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
    {% endifnotequal %}
    </p>
    <table id="debugQueryTable" style="display: none;">
      <col width="1"></col>
      <col></col>
      <col width="1"></col>
      <thead>
        <tr>
          <th scope="col">#</th>
          <th scope="col">SQL</th>
          <th scope="col">Time</th>
        </tr>
      </thead>
      <tbody>
        {% for query in sql_queries %}
          <tr class="{% cycle odd,even %}">
            <td>{{ forloop.counter }}</td>
            <td>{{ query.sql|escape }}</td>
            <td>{{ query.time }}</td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
{% endif %}

Я получил переменнуюsql_time_sum добавив строку

context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])

к функции отладки в django_src / django / core / context_processors.py.

 15 авг. 2017 г., 11:45
Я только что попробовал это, и (удалив часть sql_time_sum), получил: Нет именованных циклов в шаблоне. & APOS; нечетное, даже & APOS; не определено - что мне не хватает?

см. Параметры ведения журнала в settings.py, описанные в этом посте.

http://dabapps.com/blog/logging-sql-queries-django-13/

debug_toolbar замедляет загрузку каждой страницы на вашем dev-сервере, ведение журнала не делает это быстрее. Выходы могут быть выгружены в консоль или файл, поэтому пользовательский интерфейс не так хорош. Но для представлений с большим количеством SQL может потребоваться много времени для отладки и оптимизации SQL через debug_toolbar, поскольку загрузка каждой страницы очень медленная.

 11 мар. 2016 г., 18:41
Отлично! Хотя панель инструментов выглядит великолепно, я думаю, что этот ответ должен быть принятым. Это решение, которое я хотел, потому что оно позволяет «manage.py runserver» quot; зарегистрируйте SQL в консоли, и он будет работать с «manage.py migrate». Последнее позволило мне увидеть, что "на каскаде удаления" определенно не был установлен, когда мои таблицы созданы. Стоит отметить, что этот ответ основан наdocs.djangoproject.com/en/1.9/topics/logging/…

чтобы вы могли легко разместить декоратор в вашей функции просмотра и посмотреть, сколько запросов выполнено.

Установить:

$ 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

tail -f /var/log/postgresql/*

Предполагалось, что postgres 10.6, ubuntu 18.04+, python3 +, django2 + и что регистрация включена в postgres.

debug_toolbarэто очень полезно для отладки.

Документация и источник доступны по адресуhttp://django-debug-toolbar.readthedocs.io/.

Screenshot of debug toolbar

 16 авг. 2012 г., 19:20
debug_toolbar особенно полезен, когда у вас есть запрос, который не выполняется с ошибкой синтаксиса SQL; он будет отображать последний запрос, который попытался выполнить (и потерпел неудачу), упрощая отладку.

from django.db import connections
from app_name import models
from django.utils import timezone

# Generate a queryset, use your favorite filter, QS objects, and whatnot.
qs=models.ThisDataModel.objects.filter(user='bob',date__lte=timezone.now())

# Get a cursor tied to the default database
cursor=connections['default'].cursor()

# Get the query SQL and parameters to be passed into psycopg2, then pass
# those into mogrify to get the query that would have been sent to the backend
# and print it out. Note F-strings require python 3.6 or later.
print(f'{cursor.mogrify(*qs.query.sql_with_params())}')
 25 окт. 2018 г., 16:24
IIRC Cursor.mogrify возвращает строку, поэтому я предполагаю, что использование строки f для форматирования является излишним.
 25 окт. 2018 г., 11:14
Это работало даже в Python 2. Только рефакторинг, такой как print (cursor.mogrify (* qs.query.sql_with_params ())) - все, что ему нужно.
Решение Вопроса

Как я могу увидеть необработанные SQL-запросы, которые выполняет Django?& Quot;

django.db.connection.queries содержит список запросов SQL:

from django.db import connection
print connection.queries

Querysets также имеютquery attribute содержащий запрос для выполнения:

print MyModel.objects.filter(name="my name").query

Обратите внимание, что вывод запроса не является допустимым SQL, потому что:

"Django never actually interpolates the parameters: it sends the query and the parameters separately to the database adapter, which performs the appropriate operations."

Из сообщения об ошибке Django#17741.

Из-за этого вы не должны отправлять вывод запроса непосредственно в базу данных.

 02 февр. 2012 г., 10:14
или просто напиши ответ! Потому что люди, подобные мне, ищут решение ...
 07 июл. 2014 г., 16:51
Обратите внимание, что выходquery SQL недопустим, потому что «Django никогда не интерполирует параметры: он отправляет запрос и параметры отдельно адаптеру базы данных, который выполняет соответствующие операции». Источник:code.djangoproject.com/ticket/17741
 14 июн. 2012 г., 13:40
атрибут запроса? что? где это - я проверил ссылку, но это гигантский, не алфавитный (зачем кому-то составлять список, не являющийся алфавитным?) списком ...
 02 июл. 2009 г., 15:31
Чтобы подтвердить этот ответ на будущее, вам следует связать текущую версию документации Django:docs.djangoproject.com/en/dev/faq/models/…
 24 июл. 2013 г., 07:55
Отличный ответ. Тем не менее, рекомендуется использовать указанный встроенный Pythonianstr() функция, которая вызывает внутренний__str__() метод. напримерstr(MyModel.objects.filter(name="my name").query)  Я также рекомендовал бы использовать IPython и оболочку Django вашего проекта. Завершение вкладки обеспечивает самоанализ объекта. Так как Django известен своими утвержденными схемами именования, эта методология имеет тенденцию быть очень полезной.

Я считаю, что самый полезный, простой и надежный способ - спросить вашу базу данных. Например, в Linux для Postgres вы можете сделать:

sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log

У каждой базы данных будет немного другая процедура. В журналах базы данных вы увидите не только необработанный SQL, но и любые установки соединения или накладные расходы на транзакции, которые django размещает в системе.

 22 февр. 2016 г., 12:33
не забудьте установитьlog_statement='all' вpostgresql.conf для этого метода.

https://code.djangoproject.com/ticket/17741:

def str_query(qs):
    """
    qs.query returns something that isn't valid SQL, this returns the actual
    valid SQL that's executed: https://code.djangoproject.com/ticket/17741
    """
    cursor = connections[qs.db].cursor()
    query, params = qs.query.sql_with_params()
    cursor.execute('EXPLAIN ' + query, params)
    res = str(cursor.db.ops.last_executed_query(cursor, query, params))
    assert res.startswith('EXPLAIN ')
    return res[len('EXPLAIN '):]
q = Query.objects.values('val1','val2','val_etc')

print q.query
 16 дек. 2015 г., 00:04
или жеstr(q.query)

Ваш ответ на вопрос