web-dev-qa-db-fra.com

Django: affiche / enregistre les appels SQL ORM depuis python

En utilisant l'excellent Django-Devserver je trouve toutes sortes d'appels SQL intéressants et inattendus dans mon code. Je voulais trouver d'où venaient les appels, et je cherche donc un moyen d'obtenir un journal ou une impression de tous les appels SQL générés par l'ORM Django dans le Python Coquille. Autrement dit, lorsque j'effectue un appel Django ORM via le shell [Python, j'aimerais voir le SQL résultant imprimé ou enregistré.

J'ai remarqué plusieurs solutions qui ajoutent des informations de journal à la page html. Existe-t-il un moyen simple de basculer vers la ligne de commande?

53
Parand

Si vous êtes dans le Shell, ou n'importe où d'ailleurs, vous pouvez utiliser la méthode queryset

query.as_sql()

pour imprimer la commande SQL.

c'est à dire:

MyModel.objects.all().query.as_sql()
11
Zach

Si vous utilisez Django 1.3:

import logging
l = logging.getLogger('Django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
184
jacobian

Django Debug Toolbar de Rob Hudson, ainsi que son impression générale, inclut également une commande astucieuse debugsqlshell manage.py qui fait exactement cela.

29
Daniel Roseman

J'essayais d'utiliser " Django: afficher/enregistrer les appels SQL ORM de python Shell " dans un Shell sur un serveur de production, et cela ne fonctionnait pas. Finalement quelqu'un a souligné qu'il ne ferait cette journalisation de débogage que lorsque DEBUG = True. Mais vous pouvez contourner cela comme ceci:

import logging
from Django.db import connection
connection.force_debug_cursor = True  # Change to use_debug_cursor in Django < 1.8
l = logging.getLogger('Django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())

Je laisse cela ici pour que je puisse le retrouver plus tard, et j'espère que cela permettra à quelqu'un d'autre de faire les mêmes fouilles que moi.

27
babbageclunk

Utilisez les extensions Django.

pip install Django-extensions
./manage.py Shell_plus --print-sql

Pour les environnements de production, cela peut ne pas fonctionner en raison des paramètres de débogage.

19
Venkat Kotra
qs = YourModel.objects.all()

qs.query.get_compiler('default').as_sql()
6
cooncesean

Si vous voulez vraiment voir/enregistrer toutes les requêtes SQL, vous voudrez essayer Django 1.3 (actuellement en alpha, mais bientôt en production) qui permet Enregistreurs Python pour de nombreux composants, y compris les backends de base de données.

Bien sûr, si vous êtes bloqué en utilisant une version stable de Django, vous pouvez obtenir le même effet relativement facilement en corrigeant Django/db/models/sql/compiler.py En l'ajoutant au bas de la liste d'importation:

import logging
_querylogger = logging.getLogger( 'sql.compiler' )

Trouvez la méthode SQLCompiler::execute_sql() et changez:

    cursor = self.connection.cursor()
    cursor.execute( sql, params )

pour ça:

    cursor = self.connection.cursor()
    _querylogger.info( "%s <= %s", sql, params )
    cursor.execute( sql, params )
5
Craig Trader