#database #django #python #sql

When you are debugging an app using Django, it's sometimes really useful to see the raw SQL queries your app is executing. It helps you in understanding how the SQL queries are built by Django and it also helps you to pinpoint performance problems and optimize the queries.

You can enable the logging by adding the following snippet to your apps settings.py file:

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

When you then run your app, you will see each SQL query as it's executed in the output of e.g. the runserver command:

$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
(0.020) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.029) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
(0.018) SHOW FULL TABLES; args=None
(0.018) SELECT `django_migrations`.`id`, `django_migrations`.`app`, `django_migrations`.`name`, `django_migrations`.`applied` FROM `django_migrations`; args=()
November 05, 2020 - 17:31:19
Django version 3.1.3, using settings 'mysite.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

To avoid that you accidently enable this in production, I generally add an extra if-statement around this in the settings.py file so that it only runs when a specific environment variable is set (in my setup, it's called DEBUG_SQL):

if os.environ.get('DEBUG_SQL', '0') == '1':
    LOGGING = {
        ...
    }

More info can be found in the Django documentation.