Skip to main content

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 uses CursorDebugWrapper)

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_sqllogging-1.0.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_sqllogging-1.0.0-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

File details

Details for the file django_sqllogging-1.0.0.tar.gz.

File metadata

  • Download URL: django_sqllogging-1.0.0.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

Hashes for django_sqllogging-1.0.0.tar.gz
Algorithm Hash digest
SHA256 698af3ac0d1f998b931a04a879db5231f0d42fe621dbd593f2f763404a09f8e7
MD5 42c3cb665196f521929f6da083bb06db
BLAKE2b-256 cd9ff31931fbf909df977fa8e7604241a95e23358337d092f5bfe506e86ee11d

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_sqllogging-1.0.0.tar.gz:

Publisher: publish.yml on simonpercivall/django-sqllogging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_sqllogging-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_sqllogging-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e5bcd65935a1c7ebfcb3193b054f976bd2d9b17ff633675cd821aeb046e8789
MD5 c3d3eb6ab9d61dfd04f6f49c6e23feeb
BLAKE2b-256 9b381f49e2b28ef6dd3dd87b40f84530840197ffc33ac54c1a69fbe3d1606a34

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_sqllogging-1.0.0-py3-none-any.whl:

Publisher: publish.yml on simonpercivall/django-sqllogging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page