Comment afficher la requête SQL correspondante du jeu de requêtes de Django ORM?

164

Existe-t-il un moyen d'imprimer la requête générée par Django ORM?

Disons que j'exécute l'instruction suivante: Model.objects.filter(name='test')

Comment puis-je voir la requête SQL générée?

Jarvis
la source

Réponses:

178

Chaque objet QuerySet possède un queryattribut que vous pouvez enregistrer ou imprimer sur stdout à des fins de débogage.

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

Éditer

J'ai également utilisé des balises de modèle personnalisées (comme indiqué dans cet extrait de code) pour injecter les requêtes dans le cadre d'une seule demande sous forme de commentaires HTML.

Joe Holloway
la source
6
qu'en est-il des requêtes pour .save ()?
DataGreed
@DataGreed Bonne question, pourrait valoir la peine d'être posée dans un nouveau fil de discussion pour obtenir plus de réponses.
Joe Holloway
4
Fonctionne-t-il avec prefetch_relatedie show 2 requêtes? Je ne vois que 1.
utilisateur
ne fonctionne pas. je vois<django.db.models.sql.query.Query object
dopatraman
Essayez print (str (qs.query)). Je pense qu'ils ont changé un peu les éléments internes en 10 ans
Joe Holloway
114

Vous pouvez également utiliser la journalisation python pour journaliser toutes les requêtes générées par Django. Ajoutez simplement ceci à votre fichier de paramètres.

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

Une autre méthode au cas où l'application génère une sortie html - la barre d'outils de débogage django peut être utilisée.

aisbaa
la source
3
Si quelqu'un souhaite avoir un résumé avec le résumé du nombre de requêtes exécutées ainsi que le temps total qu'il a fallu: dabapps.com/blog/logging-sql-queries-django-13
andilabs
9
Cela n'a pas fonctionné pour moi, j'ai dû ajouter 'level': 'DEBUG'sous 'django.db'.
rvernica
108

Vous pouvez coller ce code sur votre shell qui affichera toutes les requêtes 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
la source
72

Tant qu'il DEBUGest allumé:

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

Pour une requête individuelle, vous pouvez faire:

print(Model.objects.filter(name='test').query)
Daniel Roseman
la source
22
Note aux lecteurs: queryrenvoie un Queryobjet depuis Djagno 1.2 qui n'a pas d' as_sqlattribut.
Davor Lucic
30

Vous devriez peut-être jeter un œil à l' django-debug-toolbarapplication, elle enregistrera toutes les requêtes pour vous, affichera les informations de profilage pour elles et bien plus encore.

Mikhail Korobov
la source
3
Ceci est très utile, mais cela ne fonctionne que dans l'interface graphique et parfois vous voulez voir les journaux de requêtes directement dans ORM. par exemple, vous avez une API, sans interface graphique!
wim le
3

Une solution robuste consisterait à enregistrer votre serveur de base de données dans un fichier, puis

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

Si vous utilisez le routage de base de données, vous disposez probablement de plusieurs connexions à la base de données. Un code comme celui-ci vous permet de voir les connexions dans une session. Vous pouvez réinitialiser les statistiques de la même manière qu'avec une seule connexion: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
la source
1

Vous pouvez utiliser une debug_toolbar Django pour afficher la requête SQL. Guide étape par étape pour l'utilisation de debug_toolbar:

Installez la Debug_toolbar

pip install django-debug-toolbar

Modifiez le fichier settings.py et ajoutez debug_toolbar aux applications installées, cela devrait être ajouté ci-dessous à «django.contrib.staticfiles». Ajoutez également debug_toolbar au middleware.

Settings.py =>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

créer une nouvelle liste nommée INTERNAL_IPS dans le fichier settings.py

Settings.py => créer une nouvelle liste à la fin du fichier settings.py et ajouter la liste ci-dessous:

INTERNAL_IPS= [127.0.0.1']

Cela permettra au débogage de s'exécuter uniquement sur le serveur de développement interne

Modifiez le fichier urls.py de #Project et ajoutez le code ci-dessous:

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

appliquer à nouveau migrer et exécuter le serveur

Vous verrez un module complémentaire sur votre page Web à 127.0.0.1 et si vous cliquez sur la case à cocher Requête SQL, vous pouvez également voir le temps d'exécution de la requête.

Devesh G
la source