journaliser toutes les requêtes SQL

98

Comment puis-je enregistrer toutes les requêtes SQL effectuées par mon application django?

Je veux tout consigner, y compris les SQL du site d'administration. J'ai vu cette question et une réponse à la FAQ, mais je ne sais toujours pas où dois-je mettre

from django.db import connection
connection.queries

tout consigner dans un seul fichier?

Ma question est donc: que dois-je faire pour avoir un fichier (disons all-sql.log) où toutes les instructions SQL sont enregistrées?

Oleg Pavliv
la source
stackoverflow.com/questions/1074212/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

19

Consultez peut-être https://github.com/django-debug-toolbar/django-debug-toolbar

Cela vous permettra de voir toutes les requêtes générées par une page donnée. Ainsi que les traces de leur emplacement, etc.

EDIT: pour enregistrer toutes les requêtes SQL dans un fichier, etc., vous voudrez alors créer un middleware. L'intergiciel s'exécute à chaque demande. Il existe plusieurs extraits Django pour ce genre de chose:

Ceux-ci concernent l'impression sur le terminal, mais il ne serait pas difficile de les adapter pour utiliser la bibliothèque de journalisation de python.

John Montgomery
la source
177

Fusionner l'extrait de code suivant avec le LOGGINGchamp dans votre settings.py:

LOGGING = {
    'version': 1,
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        }
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        }
    }
}

Modification de la réponse @ acardenas89

Gian Marco
la source
3
vous devrez peut-être ajouter ce qui suit à la handlerssection au cas où vous obtenez Impossible d'ajouter le gestionnaire 'console': erreur 'console' : 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'verbose', 'stream': sys.stderr, },
Don Grem
1
J'avais également besoin 'version': 1,dans le LOGGINGdict.
Dan
12
Veuillez noter que DEBUG doit être TRUE pour que les journaux soient réellement enregistrés. Indépendamment des paramètres de journalisation.
Janusz Skonieczny
3
Oh, et encore une chose dans django coureur de test ne tient pas compte des paramètres et des dérogations DEBUGà False, donc dans le test , vous devez@override_settings(DEBUG=True)
Janusz Skonieczny
7
J'ajouterais également 'propagate': Falseaprès la 'handlers': ['console'],ligne, au cas où vous auriez un enregistreur de racine activé et que vous ne sauriez pas pourquoi cela s'imprime deux fois. Il m'a fallu un peu de temps pour réaliser.
Andrei-Niculae Petre
44

Ajoutez les instructions en gras suivantes dans settings.py


si DEBUG:
    journalisation des importations
    l = logging.getLogger ('django.db.backends')
    l.setLevel (logging.DEBUG)
    l.addHandler (journalisation.StreamHandler ())


LOGGING = {
    'version 1,
    'disable_existing_loggers': Faux,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'niveau': 'ERREUR',
            'filtres': ['require_debug_false'],
            'classe': 'django.utils.log.AdminEmailHandler'
        }, 'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        } ,
    },
    'enregistreurs': {
        'django.request': {
            'gestionnaires': ['mail_admins'],
            'niveau': 'ERREUR',
            'propager': vrai,
        }, 'django.db.backends.sqlite3': {
            'level': 'DEBUG',
            'handlers': ['console'],
        } ,
    }
}
  

Ressource / crédit

cevaris
la source
9
Vous n'avez pas besoin à la fois de la ifdéclaration en haut et des LOGGINGmodifications. La ifdéclaration est pour si vous voulez ajouter la journalisation pendant que, par exemple, dans le shell, pour l'activer immédiatement - tout ce dont vous avez besoin dans settings.py, ce sont les LOGGINGmodifications - et vous voudrez peut-être django.db.backends, pas celle spécifique à sqlite3.
M Somerville
Je ne vois aucune requête sur la console exécutant django 1.9. DEBUG = True.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Ceci est un commentaire très ancien, très probablement Django 1.9 ne supporte pas cette solution de la même manière.
cevaris
Dans Django 1.9, le DEBUGparamètre est forcé à être False lors de l'exécution des tests. Une solution de contournement consiste à le réactiver dans le test
Divers
7

Pour consigner les requêtes SQL pendant les tests, vous avez besoin de deux choses:

  1. django.db.backends enregistreur activé et
  2. @override_settings(DEBUG=True) décorateur.

Le testeur définira DEBUG = False par défaut, en ignorant ce que vous avez peut-être défini dans DJANGO_SETTINGS_MODULE.

Les paramètres minimum:

# https://docs.djangoproject.com/en/dev/ref/settings/#logging
LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
        },
    },
    'root': {
        'handlers': ['console'],
    }
}

L'exemple de cas de test:

from django.contrib.auth.models import User
from django.test import TestCase, override_settings


class UserTests(TestCase):

    # To log queries in tests you need to manually override DEBUG setting
    # because testing sets DEBUG=False by default

    @override_settings(DEBUG=True)
    def test_create_user(self):
        User.objects.create()
Janusz Skonieczny
la source
2

Tu a juste besoins:

@override_settings(DEBUG=True)

si vous avez déjà des instructions de débogage SQL en cours d'impression runserver.

Ajoutez le décorateur à votre class TestA(TestCase)ou test_function:

@override_settings(DEBUG=True)
class TestA(TestCase):
...

    @override_settings(DEBUG=True)
    def test_function(self):
    ...

Crédits à la réponse de @Janusz Skonieczny!

védant
la source
0

Vous devez mettre cela dans un package middleware. Le middleware se situe entre le noyau du serveur web / django et toutes vos vues. Il peut effectuer un prétraitement avant la demande et un post-traitement une fois la demande terminée. Par exemple, enregistrez les requêtes dans un fichier.

vdboor
la source