367 votes

Récupérer le SQL d'un QuerySet Django

Comment obtenir le SQL que Django utilisera sur la base de données à partir d'un objet QuerySet ? J'essaie de déboguer un comportement étrange, mais je ne suis pas sûr des requêtes qui sont envoyées à la base de données.

7 votes

Il ne s'agit pas d'un doublon. La question liée est un sujet tout à fait différent.

1 votes

@Wooble ce n'est pas un duplicata. C'est dans le même domaine que l'autre question mais cette question concerne une requête spécifique, pas TOUTES les requêtes.

582voto

jpwatts Points 2671

Vous imprimez les données du queryset query attribut.

>>> queryset = MyModel.objects.all()
>>> print(queryset.query)
SELECT "myapp_mymodel"."id", ... FROM "myapp_mymodel"

0 votes

J'ai trouvé este qui le mentionne implicitement mais rien qui documente explicitement ce qui précède.

40 votes

Notez que la sortie de query n'est pas du SQL valide, car "Django n'interpole jamais réellement les paramètres : il envoie la requête et les paramètres séparément à l'adaptateur de base de données, qui effectue les opérations appropriées." Source : code.djangoproject.com/ticket/17741

0 votes

Où je dois écrire une requête... MyModel est une classe qui se trouve dans le fichier models.py... Mon problème est de savoir où je dois écrire la requête sql pour récupérer la valeur de la table.

61voto

Mike Axiak Points 6349

Facile :

print my_queryset.query

Par exemple :

from django.contrib.auth.models import User
print User.objects.filter(last_name__icontains = 'ax').query

Il faut également mentionner que si vous avez DEBUG = True, toutes vos requêtes sont enregistrées, et vous pouvez les obtenir en accédant à connection.queries :

from django.db import connections
connections['default'].queries

Le site barre d'outils de débogage de django s'en sert pour présenter les requêtes sur une page de manière soignée.

3 votes

Cela ne produit pas toujours un SQL valide, voir les autres réponses.

2 votes

Il n'y a aucun moyen d'obtenir le SQL réel sans exécuter la requête au préalable, le SQL final est généré par le pilote du SGBDR environnant, pas par Django. La réponse est correcte car c'est le maximum que vous pouvez obtenir avec Django QuerySet.

61voto

Hakan B. Points 656

La réponse acceptée n'a pas fonctionné pour moi lorsque j'ai utilisé Django 1.4.4. Au lieu de la requête brute, une référence à l'objet Query était renvoyée : <django.db.models.sql.query.Query object at 0x10a4acd90> .

La suite a retourné la requête :

>>> queryset = MyModel.objects.all()
>>> queryset.query.__str__()

31 votes

Ça n'a probablement pas marché parce que tu as juste tapé queryset.query au lieu de print queryset.query qui appelle __str__()

15 votes

@hughes a raison. Si vous ne voulez pas l'imprimer et que vous le voulez sous forme de chaîne, au lieu d'appeler __str__() pour l'obtenir sous forme de chaîne, vous devez faire str(queryset.query) .

1 votes

J'utilise ipdb pour déboguer et il imprime une référence à l'objet de requête quand je fais p queryset . p queryset.__str__() produit le résultat souhaité, c'est donc une meilleure réponse.

12voto

Guillaume Esquevin Points 1990

Ce middleware affichera chaque requête SQL sur votre console, avec une mise en évidence par couleur et le temps d'exécution. Il m'a été très utile pour optimiser certaines requêtes délicates.

http://djangosnippets.org/snippets/290/

12voto

Tomasz Zielinski Points 9300

Comme alternative aux autres réponses, django-devserver envoie le SQL à la console.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X