catat semua kueri sql


98

Bagaimana saya bisa mencatat semua query SQL yang dijalankan oleh aplikasi django saya?

Saya ingin mencatat semuanya, termasuk SQL dari situs admin. Saya melihat pertanyaan ini dan jawaban FAQ tetapi saya masih tidak tahu di mana saya harus meletakkan

from django.db import connection
connection.queries

memasukkan semuanya ke satu file?

Jadi pertanyaan saya adalah - apa yang harus saya lakukan untuk memiliki file (katakanlah all-sql.log) di mana semua pernyataan SQL dicatat?


Jawaban:


19

Mungkin lihat https://github.com/django-debug-toolbar/django-debug-toolbar

Ini akan memungkinkan Anda melihat semua kueri yang dihasilkan oleh halaman tertentu. Serta pelacakan tumpukan di mana mereka terjadi dll.

EDIT: untuk mencatat semua kueri SQL ke file dll, maka Anda akan ingin membuat beberapa middleware. Middleware dijalankan pada setiap permintaan. Ada beberapa potongan Django di luar sana untuk hal semacam ini:

Mereka prihatin dengan pencetakan ke terminal, tetapi tidak akan sulit untuk menyesuaikannya untuk menggunakan perpustakaan logging python.


177

Gabungkan cuplikan berikut dengan LOGGINGbidang di Anda 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'],
        }
    }
}

Tweak dari @ acardenas89 jawaban


3
Anda mungkin perlu menambahkan yang berikut ini ke handlersbagian ini jika Anda tidak dapat menambahkan handler 'console': kesalahan 'console' : 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'verbose', 'stream': sys.stderr, },
Don Grem

1
Saya juga diperlukan 'version': 1,dalam LOGGINGdict.
Dan

12
Harap dicatat bahwa DEBUG harus BENAR agar log benar-benar dicatat. Terlepas dari pengaturan logging.
Janusz Skonieczny

3
Oh, dan satu hal lagi dalam Django uji runner mengabaikan pengaturan dan menimpa DEBUGuntuk False, sehingga dalam tes Anda harus@override_settings(DEBUG=True)
Janusz Skonieczny

7
Saya juga akan menambahkan 'propagate': Falsesetelah 'handlers': ['console'],baris, jika Anda mengaktifkan logger root dan tidak tahu mengapa ini dicetak dua kali. Butuh sedikit waktu bagiku untuk menyadari.
Andrei-Niculae Petre

44

Tambahkan pernyataan tebal berikut di settings.py


jika DEBUG:
    impor penebangan
    l = logging.getLogger ('django.db.backends')
    l.setLevel (logging.DEBUG)
    l.addHandler (logging.StreamHandler ())


LOGGING = {
    'versi 1,
    'disable_existing_loggers': Salah,
    'filter': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'penangan': {
        'mail_admins': {
            'level': 'ERROR',
            'filter': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }, 'konsol': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        } ,
    },
    'penebang': {
        'django.request': {
            'penangan': ['mail_admins'],
            'level': 'ERROR',
            'propagate': Benar,
        }, 'django.db.backends.sqlite3': {
            'level': 'DEBUG',
            'penangan': ['konsol'],
        } ,
    }
}
  

Sumber Daya / Kredit


9
Anda tidak membutuhkan ifpernyataan di atas dan LOGGINGperubahannya. The ifpernyataan adalah karena jika Anda ingin menambahkan logging sementara misalnya di shell, untuk menyalakannya segera - semua yang Anda butuhkan dalam settings.py adalah LOGGINGperubahan - dan Anda mungkin juga ingin django.db.backends, bukan satu sqlite3 tertentu.
M Somerville

Saya tidak melihat kueri apa pun di konsol yang menjalankan django 1.9. DEBUG = True.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Ini adalah komentar yang sangat lama, sangat mungkin Django 1.9 tidak mendukung solusi yang sama.
cevaris

Dalam Django 1.9, DEBUGpengaturan dipaksa menjadi False saat menjalankan percobaan. Solusinya adalah mengaktifkannya kembali dalam pengujian
Mouscellaneous


7

Untuk mencatat kueri SQL selama pengujian, Anda memerlukan dua hal:

  1. django.db.backends logger diaktifkan dan
  2. @override_settings(DEBUG=True) penghias.

Runner pengujian akan menyetel DEBUG = False secara default, mengabaikan apa yang mungkin telah Anda setel di DJANGO_SETTINGS_MODULE.

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

Contoh kasus uji:

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

Anda hanya membutuhkan:

@override_settings(DEBUG=True)

jika Anda sudah mencetak pernyataan debug SQL runserver.

Tambahkan dekorator ke class TestA(TestCase)atau test_function:

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

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

Penghargaan untuk jawaban @Janusz Skonieczny!


0

Anda harus memasukkan ini ke dalam paket middleware. Middleware berada di antara webserver / inti django dan semua pandangan Anda. Ia dapat melakukan preprocessing sebelum permintaan, dan postprocessing setelah permintaan selesai. Misalnya, simpan kueri ke file.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.