Jak wyświetlić odpowiednie zapytanie SQL z zestawu zapytań Django ORM?

164

Czy istnieje sposób na wydrukowanie zapytania generowanego przez Django ORM?

Powiedz, że wykonuję następującą instrukcję: Model.objects.filter(name='test')

Jak mogę zobaczyć wygenerowane zapytanie SQL?

Jarvis
źródło

Odpowiedzi:

178

Każdy obiekt QuerySet ma queryatrybut, który można rejestrować lub drukować na standardowe wyjście w celu debugowania.

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

Edytować

Użyłem również niestandardowych tagów szablonów (jak opisano w tym fragmencie ), aby wprowadzić zapytania w zakresie pojedynczego żądania jako komentarze HTML.

Joe Holloway
źródło
6
a co z zapytaniami o .save ()?
DataGreed
@DataGreed Dobre pytanie, warto zadać je w nowym wątku, aby uzyskać więcej odpowiedzi.
Joe Holloway
4
Czy działa z prefetch_relatednp. Pokaż 2 zapytania? Widzę tylko 1.
użytkownik
nie działa. widzę<django.db.models.sql.query.Query object
dopatraman
Spróbuj print (str (qs.query)). Myślę, że zmienili trochę wnętrze w ciągu 10 lat
Joe Holloway
114

Możesz również użyć rejestrowania w Pythonie do rejestrowania wszystkich zapytań generowanych przez Django. Po prostu dodaj to do pliku ustawień.

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
        },
    },
}

Inną metodą w przypadku, gdy aplikacja generuje wyjście html - można użyć paska narzędzi debugowania django .

aisbaa
źródło
3
Jeśli ktoś chciałby mieć podsumowanie z sumup od liczby wykonanych zapytań , a także całkowitego czasu zajęło: dabapps.com/blog/logging-sql-queries-django-13
andilabs
9
U mnie to nie zadziałało, musiałem dodać 'level': 'DEBUG'pod 'django.db'.
rvernica
108

Możesz wkleić ten kod do swojej powłoki, która wyświetli wszystkie zapytania 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())
Pramod
źródło
72

Tak długo, jak DEBUGjest włączone:

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

W przypadku pojedynczego zapytania możesz wykonać:

print(Model.objects.filter(name='test').query)
Daniel Roseman
źródło
22
Uwaga dla czytelników: queryzwraca Queryobiekt od Djagno 1.2, który nie ma as_sqlatrybutu.
Davor Lucic
30

Może powinieneś rzucić okiem na django-debug-toolbaraplikację, która będzie logować za Ciebie wszystkie zapytania, wyświetlać dla nich informacje o profilowaniu i wiele więcej.

Michaił Korobow
źródło
3
Jest to bardzo przydatne, ale działa tylko w GUI i czasami chcesz zobaczyć dzienniki zapytań bezpośrednio w ORM. np. masz api bez GUI!
wim
3

Solidnym rozwiązaniem byłoby zapisanie dziennika serwera bazy danych do pliku, a następnie

tail -f /path/to/the/log/file.log
alan
źródło
2

Jeśli używasz routingu bazy danych, prawdopodobnie masz więcej niż jedno połączenie z bazą danych. Taki kod pozwala zobaczyć połączenia w sesji. Możesz zresetować statystyki w taki sam sposób, jak w przypadku pojedynczego połączenia: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() )
Tim Richardson
źródło
1

Aby wyświetlić zapytanie SQL, możesz użyć paska debug_toolbar Django. Przewodnik krok po kroku dotyczący użycia paska narzędzi debug_toolbar:

Zainstaluj Debug_toolbar

pip install django-debug-toolbar

Edytuj plik settings.py i dodaj pasek debug_toolbar do zainstalowanych aplikacji, należy to dodać poniżej do „django.contrib.staticfiles”. Dodaj także debug_toolbar do oprogramowania pośredniego.

Settings.py =>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

utwórz nową listę o nazwie INTERNAL_IPS w pliku settings.py

Settings.py => utwórz nową listę na końcu pliku settings.py i dodaj poniższą listę:

INTERNAL_IPS= [127.0.0.1']

Umożliwi to debugowanie tylko na wewnętrznym serwerze deweloperskim

Edytuj plik urls.py #Project i dodaj poniższy kod:

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

ponownie zastosuj migrację i uruchomienie serwera

Zobaczysz dodatek na swojej stronie internetowej pod adresem 127.0.0.1 i jeśli klikniesz pole wyboru Zapytanie SQL, możesz również zobaczyć czas wykonywania zapytania.

Devesh G
źródło