Wie kann ich die entsprechende SQL-Abfrage des Django ORM-Abfragesets anzeigen?

164

Gibt es eine Möglichkeit, die vom Django ORM generierte Abfrage zu drucken?

Angenommen, ich führe die folgende Anweisung aus: Model.objects.filter(name='test')

Wie kann ich die generierte SQL-Abfrage anzeigen?

Jarvis
quelle

Antworten:

178

Jedes QuerySet-Objekt verfügt über ein queryAttribut, das Sie zu Debugging-Zwecken in stdout protokollieren oder drucken können.

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

Bearbeiten

Ich habe auch benutzerdefinierte Vorlagen-Tags (wie in diesem Snippet beschrieben ) verwendet, um die Abfragen im Rahmen einer einzelnen Anforderung als HTML-Kommentare einzufügen.

Joe Holloway
quelle
6
Was ist mit Abfragen für .save ()?
DataGreed
@DataGreed Gute Frage, möglicherweise lohnt es sich, sie in einem neuen Thread zu stellen, damit Sie mehr Antworten erhalten.
Joe Holloway
4
Funktioniert es mit prefetch_relateddh 2 Abfragen anzeigen? Ich sehe nur 1.
Benutzer
funktioniert nicht Ich sehe<django.db.models.sql.query.Query object
Dopatraman
Versuchen Sie es mit print (str (qs.query)). Ich denke, sie haben die Interna in 10 Jahren ein wenig verändert
Joe Holloway
114

Sie können auch die Python-Protokollierung verwenden, um alle von Django generierten Abfragen zu protokollieren. Fügen Sie dies einfach Ihrer Einstellungsdatei hinzu.

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

Eine andere Methode für den Fall, dass die Anwendung eine HTML-Ausgabe generiert - die Django-Debug-Symbolleiste kann verwendet werden.

aisbaa
quelle
3
Wenn jemand eine Zusammenfassung mit einer Zusammenfassung der Anzahl der ausgeführten Abfragen sowie der Gesamtzeit haben möchte, die benötigt wird : dabapps.com/blog/logging-sql-queries-django-13
andilabs
9
Es dauerte nicht für mich arbeiten, musste ich hinzufügen 'level': 'DEBUG'unter 'django.db'.
Rvernica
108

Sie können diesen Code in Ihre Shell einfügen, um alle SQL-Abfragen anzuzeigen:

# 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
quelle
72

Solange eingeschaltet DEBUGist:

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

Für eine einzelne Abfrage haben Sie folgende Möglichkeiten:

print(Model.objects.filter(name='test').query)
Daniel Roseman
quelle
22
Hinweis für die Leser: queryRendite QueryObjekt seit Djagno 1.2 , die es nicht haben as_sqlAttribut.
Davor Lucic
30

Vielleicht sollten Sie sich die django-debug-toolbarAnwendung ansehen , sie protokolliert alle Abfragen für Sie, zeigt Profilinformationen für sie an und vieles mehr.

Mikhail Korobov
quelle
3
Dies ist sehr nützlich, funktioniert jedoch nur in der GUI und manchmal möchten Sie Abfrageprotokolle direkt in ORM anzeigen. zB du hast eine API ohne GUI!
wim
3

Eine robuste Lösung wäre, Ihren Datenbankserver in einer Datei protokollieren zu lassen und dann

tail -f /path/to/the/log/file.log
Alan
quelle
2

Wenn Sie Datenbankrouting verwenden, haben Sie wahrscheinlich mehr als eine Datenbankverbindung. Mit diesem Code können Sie Verbindungen in einer Sitzung anzeigen. Sie können die Statistiken wie bei einer einzelnen Verbindung zurücksetzen: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
quelle
1

Sie können eine Django debug_toolbar verwenden, um die SQL-Abfrage anzuzeigen. Schritt-für-Schritt-Anleitung zur Verwendung von debug_toolbar:

Installieren Sie die Debug_toolbar

pip install django-debug-toolbar

Bearbeiten Sie die Datei settings.py und fügen Sie debug_toolbar zu installierten Apps hinzu. Dies sollte unten zu 'django.contrib.staticfiles' hinzugefügt werden. Fügen Sie auch debug_toolbar zur Middleware hinzu.

Settings.py =>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

Erstellen Sie eine neue Liste mit dem Namen INTERNAL_IPS in der Datei settings.py

Settings.py => Neue Liste am Ende der Datei settings.py erstellen und folgende Liste hinzufügen:

INTERNAL_IPS= [127.0.0.1']

Dadurch kann das Debug nur auf dem internen Entwicklungsserver ausgeführt werden

Bearbeiten Sie die Datei urls.py von #Project und fügen Sie den folgenden Code hinzu:

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

Wenden Sie den Migrate & Run-Server erneut an

Auf Ihrer Webseite wird unter 127.0.0.1 ein Add-On angezeigt. Wenn Sie auf das Kontrollkästchen SQL-Abfrage klicken, wird auch die Laufzeit der Abfrage angezeigt.

Devesh G.
quelle