Pretty, useful SQL logging for Django development
Project description
django-sqllogging
Pretty, useful SQL logging for Django development.
- Re-formats and syntax-highlights SQL queries in the terminal
- Color-codes mutation queries (INSERT, UPDATE, DELETE, ALTER); syntax-highlights SELECTs
- Logs queries before execution with inlined parameters
- Logs query duration with slow-query highlighting
- Shows the request path that triggered each query
- Shows stack traces to find where queries originate
- Detects implicitly loaded relations (forward FK, forward/reverse one-to-one)
Installation
pip install django-sqllogging
Quick Start
Add django_sqllogging to your installed apps:
# settings.py
INSTALLED_APPS = [
# ...
"django_sqllogging",
]
Then control SQL logging via the sqldebug environment variable:
# Log all queries
sqldebug=query python manage.py runserver
# Log queries with stack traces
sqldebug=query,stack python manage.py runserver
# Log queries with the request path (requires middleware, see below)
sqldebug=query,request python manage.py runserver
# Log implicitly loaded relations
sqldebug=rels python manage.py runserver
# Everything
sqldebug=query,stack,rels,request python manage.py runserver
That's it — when sqldebug is set and no explicit logging configuration exists, a default handler is added automatically.
For custom logging setups (file output, different formatters, etc.), see Advanced Configuration.
Example Output
With sqldebug=query:
[django_sqllogging] ===>
SELECT id, name, email
FROM myapp_user
WHERE active = 1
AND role = 'admin'
ORDER BY created_at;
SQL Time: 0.0023
With sqldebug=rels:
[django_sqllogging] ===> 'profile' implicitly fetched on 'User'
Mutation queries (INSERT, UPDATE, DELETE) are color-coded. Slow queries (>0.1s by default) show the duration in red. In stack mode, a filtered stack trace appears above each query showing the application code that triggered it.
Shortcuts
| Value | Equivalent |
|---|---|
1 or t |
query |
2 |
query,stack |
trace |
stack |
0 or f |
disabled |
Request Path Tracking
To display the request path that triggered each query, add the middleware early in the list — queries from middleware above it won't have request context:
MIDDLEWARE = [
"django_sqllogging.middleware.sql_logging_middleware",
# ... other middleware
]
Then use sqldebug=query,request or sqldebug=query,stack (stack mode includes the request path automatically).
The middleware supports both WSGI and ASGI (sync and async Django).
Third-party compatibility
If you already have django-crum or django-threadlocals middleware active in your MIDDLEWARE, the built-in middleware is unnecessary — django-sqllogging auto-detects these libraries and reads the current request from them. No configuration needed.
Without any middleware (built-in or third-party), request path display silently shows nothing.
How It Works
When django_sqllogging is in INSTALLED_APPS and the logger is configured, the library patches Django's CursorDebugWrapper (used when DEBUG = True) to log queries before execution with inlined parameters. It also patches relation descriptors to detect implicit relation loading.
These patches are dormant when the sqldebug env var is not set — the overhead is negligible (one attribute check per query or relation access).
Request path tracking uses a lightweight ContextVar-based middleware (or auto-detects compatible third-party middleware) instead of walking the call stack.
Advanced Configuration
Using SqlFormatter with a different handler
SqlFormatter can be used independently with any handler (FileHandler, SysLogHandler, etc.):
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"sql": {
"()": "django_sqllogging.SqlFormatter",
"project_name": "myapp",
},
},
"filters": {
"sql_debug": {"()": "django_sqllogging.SqlDebugFilter"},
},
"handlers": {
"sql_file": {
"class": "logging.FileHandler",
"filename": "sql.log",
"formatter": "sql",
"filters": ["sql_debug"],
},
},
"loggers": {
"django_sqllogging": {"level": "DEBUG", "handlers": ["sql_file"], "propagate": False},
},
}
SqlDebugFilter suppresses records when the sqldebug env var is not set. Without it, all SQL records are written regardless of sqldebug.
Overriding SQL_DEBUG programmatically
The sqldebug env var is auto-detected at startup. To override it in settings:
SQL_DEBUG = {"query", "stack"} # Always enable query + stack mode
If SQL_DEBUG is set explicitly in settings (even to None), the env var is ignored.
Formatter Options
| Option | Default | Description |
|---|---|---|
project_name |
Last component of BASE_DIR |
Controls how stack trace paths are shortened |
slow_threshold |
0.1 (seconds) |
Duration above this is highlighted red |
max_sql_length |
10000 (chars) |
SQL longer than this is truncated |
Requirements
- Python 3.12+
- Django 5.2+ with
DEBUG = True(pre-execution logging usesCursorDebugWrapper)
See also
- nplusone — N+1 query detection for Django and SQLAlchemy with middleware-based profiling, eager-load analysis, and test-mode exceptions. Unmaintained since 2020 but stable.
License
BSD 3-Clause. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_sqllogging-1.0.1.tar.gz.
File metadata
- Download URL: django_sqllogging-1.0.1.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c908b3c811cc860f9ca8e25bacd2fcc08a5a13e0812e483cd5b75cee68bdd32d
|
|
| MD5 |
126d1974446af52ee287ca7914ea9d36
|
|
| BLAKE2b-256 |
58c6c8c3aa2b8d8112690762bc946058343219ecbf4f5906d7656c1daa60365d
|
Provenance
The following attestation bundles were made for django_sqllogging-1.0.1.tar.gz:
Publisher:
publish.yml on simonpercivall/django-sqllogging
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_sqllogging-1.0.1.tar.gz -
Subject digest:
c908b3c811cc860f9ca8e25bacd2fcc08a5a13e0812e483cd5b75cee68bdd32d - Sigstore transparency entry: 1703948543
- Sigstore integration time:
-
Permalink:
simonpercivall/django-sqllogging@cbe14d5b0620e474df145a0c49749f7b8a3733dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/simonpercivall
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cbe14d5b0620e474df145a0c49749f7b8a3733dd -
Trigger Event:
push
-
Statement type:
File details
Details for the file django_sqllogging-1.0.1-py3-none-any.whl.
File metadata
- Download URL: django_sqllogging-1.0.1-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1543ebf209025b7b46d27d02089be57f7799219b83fcf6cc4e5e1677a793887b
|
|
| MD5 |
a0971e4692a58a0c8a1bbfa96e3968ca
|
|
| BLAKE2b-256 |
78c36dbb34bf2bcf80d48c431e669262f793bb494f225dd9fa6397a83f918950
|
Provenance
The following attestation bundles were made for django_sqllogging-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on simonpercivall/django-sqllogging
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_sqllogging-1.0.1-py3-none-any.whl -
Subject digest:
1543ebf209025b7b46d27d02089be57f7799219b83fcf6cc4e5e1677a793887b - Sigstore transparency entry: 1703948563
- Sigstore integration time:
-
Permalink:
simonpercivall/django-sqllogging@cbe14d5b0620e474df145a0c49749f7b8a3733dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/simonpercivall
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cbe14d5b0620e474df145a0c49749f7b8a3733dd -
Trigger Event:
push
-
Statement type: