453 votes

Comment puis-je voir les requêtes SQL brutes que Django exécute ?

Existe-t-il un moyen d'afficher le SQL que Django exécute lors d'une requête ?

566voto

geowa4 Points 17712

Voir la docs FAQ : " Comment puis-je voir les requêtes SQL brutes que Django exécute ? "

django.db.connection.queries contient une liste des requêtes SQL :

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

Les querysets ont également un query attribut contenant la requête à exécuter :

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

Notez que la sortie de la requête 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."

Extrait du rapport de bogue de Django #17741 .

Pour cette raison, vous ne devez pas envoyer la sortie de la requête directement à une base de données.

Si vous avez besoin de réinitialiser les requêtes pour, par exemple, voir combien de requêtes sont en cours d'exécution dans une période donnée, vous pouvez utiliser la méthode suivante reset_queries de django.db :

from django.db import reset_queries

reset_queries()
print(connection.queries)
>>> []

19 votes

Pour garantir l'avenir de cette réponse, il est préférable de consulter la version actuelle de la documentation de Django : docs.djangoproject.com/en/dev/faq/models/

1 votes

Attribut de requête ? quoi ? où est-ce - j'ai vérifié le lien mais c'est une liste géante non alphabétique (pourquoi quelqu'un ferait-il une liste qui n'est pas alphabétique ?)...

8 votes

Excellente réponse. Cependant, il est recommandé d'utiliser la méthode Pythonian spécifiée et intégrée. str() qui invoque la fonction interne __str__() méthode, par exemple str(MyModel.objects.filter(name="my name").query) Je vous recommande également d'utiliser IPython et le shell Django de votre projet. La complétion par tabulation permet ensuite l'introspection des objets. Comme Django est connu pour ses schémas de nommage affirmés, cette méthodologie tend à être très utile.

71voto

Glader Points 728

Jetez un coup d'œil à debug_toolbar c'est très utile pour le débogage.

La documentation et les sources sont disponibles à l'adresse suivante http://django-debug-toolbar.readthedocs.io/ .

Screenshot of debug toolbar

3 votes

Debug_toolbar est particulièrement utile lorsque vous avez une requête qui échoue avec une erreur de syntaxe SQL ; il affichera la dernière requête qui a tenté de s'exécuter (et qui a échoué), ce qui facilite le débogage.

1 votes

La seule chose est que vous voyez les requêtes SQL sur le navigateur. Si vous exécutez des tests à partir du terminal et que vous souhaitez les voir là, ce n'est pas une solution viable. C'est quand même génial, je l'utilise encore aujourd'hui.

0 votes

Affiche toutes les requêtes comme "Aucune" si elles sont exécutées dans Docker.

40voto

jgabrielsk8 Points 31

La requête est en fait intégrée à l'API des modèles :

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

print(q.query)

0 votes

Réponse très simple ! Nice

0 votes

Cette fonctionnalité a-t-elle été supprimée ? Cela ne fonctionne pas lorsque je fais m = MyModel.objects.get(...) suivi par m.query

2 votes

C'est parce que m n'est plus un queryset. Utilisez q = MyModel.objects.filter(...) entonces q.query entonces m = q.get() .

18voto

googletorp Points 22395

Bien que vous puissiez le faire avec le code fourni, je trouve que l'utilisation de la barre d'outils de débogage est un excellent outil pour montrer les requêtes. Vous pouvez la télécharger sur github aquí .

Cela vous donne la possibilité d'afficher toutes les requêtes exécutées sur une page donnée ainsi que le temps qu'elles ont pris. Il résume également le nombre de requêtes sur une page ainsi que le temps total pour un examen rapide. C'est un excellent outil, lorsque vous voulez voir ce que l'ORM de Django fait dans les coulisses. Il comporte également de nombreuses autres fonctionnalités intéressantes, que vous pouvez utiliser si vous le souhaitez.

3 votes

Il me semble que c'est la meilleure version : github.com/django-debug-toolbar/django-debug-toolbar

11voto

Mike Howsden Points 195

Si vous vous assurez que votre fichier settings.py a :

  1. django.core.context_processors.debug répertorié dans CONTEXT_PROCESSORS
  2. DEBUG=True
  3. votre IP dans le INTERNAL_IPS tuple

Alors vous devriez avoir accès à la sql_queries variable. J'ajoute un pied de page à chaque page qui ressemble à ceci :

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

J'ai obtenu la variable sql_time_sum en ajoutant la ligne

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

à la fonction de débogage dans django_src/django/core/context_processors.py.

1 votes

Je viens d'essayer ceci, et (ayant enlevé la partie sql_time_sum), j'ai obtenu : Aucun cycle nommé dans le modèle. 'odd,even' n'est pas défini - qu'est-ce que j'ai manqué ?

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