すべてのSQLクエリをログに記録する


97

djangoアプリケーションが実行したすべてのSQLクエリをログに記録するにはどうすればよいですか?

管理サイトからのSQLを含むすべてをログに記録したい。この質問FAQの回答を見ましたが、どこに置くべきかまだわかりません

from django.db import connection
connection.queries

すべてを1つのファイルに記録するには?

だから私の質問は-すべてのSQLステートメントがログに記録されるファイル(たとえばall-sql.log)を作成するにはどうすればよいですか?


回答:


19

たぶんhttps://github.com/django-debug-toolbar/django-debug-toolbarをチェックしてください

特定のページで生成されたすべてのクエリを表示できます。それらが発生する場所のスタックトレースなども同様です。

編集:すべてのSQLクエリをファイルなどに記録するには、ミドルウェアを作成する必要があります。ミドルウェアはすべてのリクエストで実行されます。この種のもののためにそこにいくつかのDjangoスニペットがあります:

それらは端末への印刷に関心がありますが、Pythonのロギングライブラリを使用するようにそれらを適応させることは難しくありません。


176

次のスニペットを:のLOGGINGフィールドとマージします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'],
        }
    }
}

@ acardenas89の回答から微調整


3
ハンドラー「コンソール」を追加できないhandlers場合に備えて、セクションに以下を追加する必要がある場合があります。「コンソール」エラー: 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'verbose', 'stream': sys.stderr, },
Don Grem 2014年

1
私も口述で必要でし'version': 1,LOGGING
ダン

12
ログを実際にログに記録するには、DEBUGがTRUEである必要があることに注意してください。ロギング設定に関係なく。
Janusz Skonieczny 2017年

3
ああ、そしてdjangoテストランナーでもう1つ、設定を無視DEBUGしてFalseにオーバーライドするので、テストでは次のことを行う必要があります@override_settings(DEBUG=True)
Janusz Skonieczny 2017年

6
ルートロガーが有効になっていて、なぜこれが2回出力されるのかわからない場合に備えて'propagate': False'handlers': ['console'],行の後に追加します。気付くのに少し時間がかかりました。
Andrei-Niculae Petre

44

settings.pyに次の太字のステートメントを追加します


デバッグの場合:
    インポートログ
    l = logging.getLogger( 'django.db.backends')
    l.setLevel(logging.DEBUG)
    l.addHandler(logging.StreamHandler())


ロギング= {
    「バージョン」:1、
    'disable_existing_loggers':False、
    'フィルター':{
        'require_debug_false':{
            '()': 'django.utils.log.RequireDebugFalse'
        }
    }、
    'ハンドラー':{
        'mail_admins':{
            'レベル': 'エラー'、
            'filters':['require_debug_false']、
            'クラス': 'django.utils.log.AdminEmailHandler'
        }、'コンソール':{
            'レベル': 'デバッグ'、
            'クラス': 'logging.StreamHandler'、
        }、
    }、
    「ロガー」:{
        'django.request':{
            'ハンドラー':['mail_admins']、
            'レベル': 'エラー'、
            'propagate':True、
        }、'django.db.backends.sqlite3':{
            'レベル': 'デバッグ'、
            'ハンドラー':['コンソール']、
        }、
    }
}
  

リソース/クレジット


9
if上部のステートメントとLOGGING変更の両方は必要ありません。このifステートメントは、たとえばシェルでログを追加したい場合に、すぐにオンにするためのものです-settings.pyで必要なのはLOGGING変更だけです-そしてdjango.db.backends、sqlite3固有のものではなく、必要になるかもしれません。
Mサマヴィル

django1.9を実行しているコンソールにクエリが表示されません。DEBUG = True
CiroSantilli郝海东冠事病六四事件法轮功2016年

1
@CiroSantilli巴拿馬文件六四天法轮功これは本当に古いコメントです。おそらくDjango1.9はこのソリューションを同じようにサポートしていません。
cevaris 2016年

Django 1.9では、DEBUGテストの実行時に設定が強制的にFalseになります。回避策は、テストで再度有効にすることです
Mouscellaneous 2017


7

テスト中にSQLクエリをログに記録するには、次の2つが必要です。

  1. django.db.backends ロガーが有効で、
  2. @override_settings(DEBUG=True) デコレータ。

テストランナーは、DJANGO_SETTINGS_MODULEで設定した内容を無視して、デフォルトでDEBUG = Falseを設定します。

最小設定:

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

テストケースの例:

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()

2

必要なのは:

@override_settings(DEBUG=True)

SQLデバッグステートメントがすでに出力されている場合 runserver

class TestA(TestCase)またはにデコレータを追加しますtest_function

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

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

@Janusz Skoniecznyの回答のクレジット!


0

これをミドルウェアパッケージに入れる必要があります。ミドルウェアは、webserver / djangoコアとすべてのビューの間にあります。リクエストの前に前処理を行い、リクエストの完了後に後処理を行うことができます。たとえば、クエリをファイルに保存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.