Opened 6 months ago

Last modified 5 months ago

#36380 closed Bug

SQL is formatted for logging regardless of whether it will be logged — at Version 2

Reported by: Jacob Walls Owned by: Jacob Walls
Component: Database layer (models, ORM) Version: dev
Severity: Release blocker Keywords: debug-sql format_debug_sql
Cc: Tim Graham, Simon Charette, Jacob Walls, Mariusz Felisiak Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Tim Graham)

I have an endpoint that generates several large SQL strings. It performs 10x worse (300ms -> 3000ms) on the main branch. Traced it to eager formatting of SQL.

To reproduce, print or throw inside format_debug_sql(), and run a project without logging queries (i.e. without a django.db entry in LOGGING configured at the DEBUG level).

  • django/db/backends/base/operations.py

    diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py
    index fea73bc1e4..4c106f59e3 100644
    a b class BaseDatabaseOperations:  
    791791
    792792    def format_debug_sql(self, sql):
    793793        # Hook for backends (e.g. NoSQL) to customize formatting.
     794        print('eager formatting...')
    794795        return sqlparse.format(sql, reindent=True, keyword_case="upper")

Regression in d8f093908c504ae0dbc39d3f5231f7d7920dde37 (#35448).

We might want a benchmark in django-asv for views with long SQL strings?

This fix works for me; I can submit a patch with tests in the next few days:

  • django/db/backends/utils.py

    diff --git a/django/db/backends/utils.py b/django/db/backends/utils.py
    index 568f510a67..ae810ffd12 100644
    a b from hashlib import md5  
    1010from django.apps import apps
    1111from django.db import NotSupportedError
    1212from django.utils.dateparse import parse_time
     13from django.utils.functional import lazy
    1314
    1415logger = logging.getLogger("django.db.backends")
    1516
    class CursorDebugWrapper(CursorWrapper):  
    151152            logger.debug(
    152153                "(%.3f) %s; args=%s; alias=%s",
    153154                duration,
    154                 self.db.ops.format_debug_sql(sql),
     155                lazy(self.db.ops.format_debug_sql)(sql),
    155156                params,
    156157                self.db.alias,
    157158                extra={

Change History (2)

comment:1 by Simon Charette, 6 months ago

Have we considered moving the formatting logic to an actual logging formater instead? I believe these only kick in when the log is actually handled?

comment:2 by Tim Graham, 6 months ago

Description: modified (diff)
Triage Stage: UnreviewedAccepted

I had some reservations that moving the formatting from the test runner to the CursorDebugWrapper might cause some problem.

Note: See TracTickets for help on using tickets.
Back to Top