Protokollieren Sie alle SQL-Abfragen

90

Wie kann ich alle SQL-Abfragen protokollieren, die meine Django-Anwendung ausgeführt hat?

Ich möchte alles protokollieren, einschließlich SQLs von der Admin-Site. Ich habe diese Frage und eine FAQ-Antwort gesehen , kann aber immer noch nicht herausfinden, wo ich sie platzieren soll

from django.db import connection
connection.queries

alles in einer Datei protokollieren?

Meine Frage lautet also: Was soll ich tun, um eine Datei (z. B. all-sql.log) zu haben, in der alle SQL-Anweisungen protokolliert werden?

Oleg Pavliv
quelle
stackoverflow.com/questions/1074212/…
Ciro Santilli 法轮功 冠状 冠状 病 六四 事件 法轮功

Antworten:

17

Schauen Sie sich vielleicht https://github.com/django-debug-toolbar/django-debug-toolbar an

Hier können Sie alle Abfragen anzeigen, die von einer bestimmten Seite generiert wurden. Sowie Stapelspuren, wo sie auftreten usw.

BEARBEITEN: Um alle SQL-Abfragen in einer Datei usw. zu protokollieren, müssen Sie eine Middleware erstellen. Middleware wird bei jeder Anforderung ausgeführt. Es gibt mehrere Django-Schnipsel für solche Dinge:

Diese befassen sich mit dem Drucken auf dem Terminal, aber es wäre nicht schwierig, sie für die Verwendung der Protokollierungsbibliothek von Python anzupassen.

John Montgomery
quelle
172

Führen Sie das folgende Snippet mit dem LOGGINGFeld in Ihrem zusammen 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'],
        }
    }
}

Von @ acardenas89 Antwort optimiert

Gian Marco
quelle
3
Möglicherweise müssen Sie dem handlersAbschnitt Folgendes hinzufügen, falls der Handler "Konsole" nicht hinzugefügt werden kann: Fehler "Konsole" : 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'verbose', 'stream': sys.stderr, },
Don Grem
1
Ich brauchte auch 'version': 1,im LOGGINGDiktat.
Dan
12
Bitte beachten Sie, dass DEBUG TRUE sein muss, damit Protokolle tatsächlich protokolliert werden. Unabhängig von den Protokollierungseinstellungen.
Janusz Skonieczny
3
Oh, und noch eine Sache in Djangos Test Runner ignoriert Einstellungen und Überschreibungen DEBUGauf False, so in Test müssen Sie@override_settings(DEBUG=True)
Janusz Skonieczny
6
Ich würde auch 'propagate': Falsenach der 'handlers': ['console'],Zeile hinzufügen , falls Sie einen Root-Logger aktiviert haben und nicht wissen, warum dieser zweimal gedruckt wird. Ich habe ein bisschen gebraucht, um es zu realisieren.
Andrei-Niculae Petre
41

Fügen Sie die folgenden fett gedruckten Anweisungen in settings.py hinzu


wenn DEBUG:
    Protokollierung importieren
    l = logging.getLogger ('django.db.backends')
    l.setLevel (logging.DEBUG)
    l.addHandler (logging.StreamHandler ())


LOGGING = {
    'Version 1,
    'disable_existing_loggers': False,
    'Filter': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }}
    },
    'Handler': {
        'mail_admins': {
            'level': 'ERROR',
            'Filter': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }, 'Konsole': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        } ,
    },
    'Logger': {
        'django.request': {
            'Handler': ['mail_admins'],
            'level': 'ERROR',
            'propagieren': Richtig,
        }, 'django.db.backends.sqlite3': {
            'level': 'DEBUG',
            'Handler': ['Konsole'],
        } ,
    }}
}}
  

Ressource / Kredit

Cevaris
quelle
9
Sie benötigen nicht sowohl die ifAnweisung oben als auch die LOGGINGÄnderungen. Die ifAnweisung ist für den Fall, dass Sie die Protokollierung hinzufügen möchten, z. B. in der Shell, um sie sofort zu aktivieren - alles, was Sie in settings.py benötigen, sind die LOGGINGÄnderungen - und Sie möchten möglicherweise django.db.backendsnicht die sqlite3-spezifische.
M Somerville
Ich sehe keine Abfragen auf der Konsole, auf der Django 1.9 ausgeführt wird. DEBUG = True.
Ciro Santilli 法轮功 冠状 病 六四 事件 19
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Dies ist ein wirklich alter Kommentar, möglicherweise unterstützt Django 1.9 diese Lösung nicht gleich.
Cevaris
In Django 1.9 muss die DEBUGEinstellung beim Ausführen von Tests auf Falsch gesetzt werden. Eine Problemumgehung besteht darin, es im Test wieder zu aktivieren
Mouscellaneous
7

Um SQL-Abfragen während des Tests zu protokollieren, benötigen Sie zwei Dinge:

  1. django.db.backends Logger aktiviert und
  2. @override_settings(DEBUG=True) Dekorateur.

Der Testläufer setzt standardmäßig DEBUG = False und ignoriert dabei, was Sie möglicherweise in DJANGO_SETTINGS_MODULE festgelegt haben.

Die Mindesteinstellungen:

# 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'],
    }
}

Der Beispieltestfall:

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
quelle
1

Du brauchst nur:

@override_settings(DEBUG=True)

Wenn bereits SQL-Debug-Anweisungen gedruckt sind runserver.

Fügen Sie den Dekorateur zu Ihrem class TestA(TestCase)oder hinzu test_function:

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

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

Dank an die Antwort von @Janusz Skonieczny!

vedant
quelle
0

Sie müssen dies in ein Middleware-Paket packen. Die Middleware befindet sich zwischen dem Webserver / Django-Kern und all Ihren Ansichten. Es kann vor der Anforderung eine Vorverarbeitung und nach Abschluss der Anforderung eine Nachverarbeitung durchführen. Speichern Sie beispielsweise die Abfragen in einer Datei.

vdboor
quelle