2009-07-02 3 views

Odpowiedz

256

Zobacz nas dokumentów: "How can I see the raw SQL queries Django is running?"

django.db.connection.queries zawiera listę zapytań SQL:

from django.db import connection 
print connection.queries 

querysets mają również query attribute zawierający zapytanie do wykonania:

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

Należy zauważyć, że wynik zapytania nie jest poprawny SQL, ponieważ:

"Django nigdy właściwie nie interpoluje parametrów: wysyła zapytanie i parametry osobno do adaptera bazy danych, który wykonuje odpowiednie operacje."

Z raportu o błędzie Django #17741.

Z tego powodu nie należy wysyłać wyników zapytania bezpośrednio do bazy danych.

+10

Aby potwierdzić tę odpowiedź w przyszłości, powinieneś raczej połączyć aktualną wersję dokumentacji Django: http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw- sql-queries-django-is-running –

+18

lub po prostu napisz odpowiedź! Ponieważ ludzie tacy jak ja szukają rozwiązania ... – Jurudocs

+1

atrybut zapytania? co? gdzie to jest - sprawdziłem link, ale jest to gigantyczny, nie-alfabetyczny (dlaczego ktoś miałby sporządzić listę, która nie jest alfabetyczna?) lista ... – bharal

16

Chociaż można to zrobić za pomocą dostarczonego kodu, uważam, że używanie paska narzędzi debugowania jest doskonałym narzędziem do wyświetlania zapytań. Możesz pobrać go z github here.

Daje to opcję wyświetlania wszystkich zapytań wyświetlanych na danej stronie wraz z czasem wykonania zapytania. Podsumowuje również liczbę zapytań na stronie wraz z łącznym czasem do szybkiego przeglądu. To wspaniałe narzędzie, gdy chcesz spojrzeć na to, co Django ORM robi za kulisami. Ma również wiele innych ciekawych funkcji, których możesz użyć, jeśli chcesz.

+2

Wygląda na to, że jest to najlepsza wersja: https://github.com/django-debug-toolbar/django-debug-toolbar – philfreo

30

Spójrz na debug_toolbar, jest to bardzo przydatne do debugowania.

Dokumentacja i źródło są dostępne pod adresem http://django-debug-toolbar.readthedocs.io/.

Screenshot of debug toolbar

+1

debug_toolbar jest szczególnie przydatny, gdy masz zapytanie, które nie działa z błędem składni SQL; wyświetli ono ostatnie zapytanie, które próbowało uruchomić (i nie powiodło się), co ułatwia debugowanie. – scoopseven

9

Jeśli upewnić się, że plik settings.py posiada:

  1. django.core.context_processors.debug wymienione w CONTEXT_PROCESSORS
  2. DEBUG=True
  3. swój IP w INTERNAL_IPS krotki

Następnie powinieneś mieć dostęp do zmiennej sql_queries. I dołączyć stopkę do każdej strony, która wygląda tak:

{%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 %} 

mam zmienną sql_time_sum dodając linię

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

do funkcji debugowania w django_src/Django/rdzeń/context_processors.py.

+0

Po prostu próbowałem tego i (po usunięciu części sql_time_sum), otrzymałem: Brak nazwanych cykli w szablonie. "nieparzyste, równe" nie jest zdefiniowane - czego mi brakuje? – castaway

14
q = Query.objects.values('val1','val2','val_etc') 

print q.query 
+2

lub 'str (q.query)' –

7

Inna opcja, patrz Opcje zalogowaniu settings.py opisane przez tego postu

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

debug_toolbar spowalnia każde obciążenie strony na serwerze dev, rejestrowanie nie dlatego szybciej. Wyjścia można zrzucać do konsoli lub do pliku, więc interfejs użytkownika nie jest tak miły. Ale w przypadku widoków z dużą ilością instrukcji SQL może zająć dużo czasu, aby debugować i optymalizować SQL za pomocą debug_toolbar, ponieważ każde ładowanie strony jest tak powolne.

+0

Świetnie! Chociaż pasek narzędzi wygląda świetnie, myślę, że ta odpowiedź powinna być akceptowana. To jest rozwiązanie, które chciałem, ponieważ pozwala na "log SQL zarządzać" manage.py runserver do konsoli i działa z "manage.py migrate". Te ostatnie pozwoliły mi zauważyć, że "przy kasowaniu kasowania" zdecydowanie nie było ustawiane podczas tworzenia moich tabel. Warto zauważyć, że ta odpowiedź jest oparta na https://docs.djangoproject.com/en/1.9/topics/logging/#django-db-backends –

13

Żadna inna odpowiedź obejmuje tej metody, zatem:

znajdę zdecydowanie najbardziej użyteczny, prosty i niezawodny sposób jest poprosić swoją bazę danych. Na przykład w systemie Linux dla PostgreSQL można zrobić:

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

Każda baza danych będzie miał nieco inną procedurę. W dziennikach bazy danych zobaczysz nie tylko nieprzetworzony kod SQL, ale wszelkie ustawienia połączenia lub django związane z transakcją są wprowadzane do systemu.

+3

nie zapomnij ustawić 'log_statement = 'all'' w' postgresql .conf' dla tej metody. – RickyA

22

Django-extensions ma polecenie shell_plus z parametrem print-sql

./manage.py shell_plus --print-sql 

w Django skorupy wszystkie wykonane zapytania zostanie wydrukowany

np .:

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> 
+0

Używam go z --print-sql lub z SHELL_PLUS_PRINT_SQL = True i to nie pomaga - nadal nie widzę zapytań. Jakiś pomysł, dlaczego? django 1.8 – Dejell

1

następujące Zwraca zapytania jako poprawny SQL oparty na 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 '):] 
0

Zrobiłem mały fragment można użyć:

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) 

Zajmuje jako parametry funkcji (zawiera sql queryies) do wglądu i args, kwargs potrzebnych wywołać tę funkcję. W wyniku zwracana jest funkcja zwracana przez funkcję i wyprowadzane zapytania SQL w konsoli.