Skip to main content

Helper methods and mixins for debugging query issues.

Project description

Build Status Coverage Status

A Django application containing helper methods and mixins for debugging query issues.

Installation

Install package using pip install django-query-debug.

To use this package in an existing Django application, add django_query_debug to INSTALLED_APPS in your settings file.

Example:

INSTALLED_APPS = [
    'django_query_debug',
    ...
]

Usage

PatchDjangoDescriptors

Monkey patches the builtin Django field descriptors to log a warning message when a query call is about to be made. If the logging level is set to DEBUG, a stack trace will be logged to help find the line that is causing the query.

Sample usage:

from django_query_debug.patch import PatchDjangoDescriptors

PatchDjangoDescriptors() 

FieldUsageMixin

A model mixin that adds field usage tracking. Useful for determining which fields can be deferred during the initial DB query using .only() or .exclude().

To use, add the mixin to any model that extends from the Django Model class. It will wrap all model fields in that class with a custom descriptor that tracks access attempts.

Sample usage:

from django.db import models

from django_query_debug.mixins import FieldUsageMixin

class MyModel(FieldUsageMixin, models.Model):
  name = models.CharField(max_length=255)
  related_model = models.ForeignKey(...)

Calling display_field_usage() on the model will log the output field usage data. Field usage data for any related model that inherits from FieldUsageMixin will also be displayed. To exclude data from related models, use display_field_usage(show_related=False). To reset field usage data, call reset_field_usage() on that object.

Note: If a related object is referenced more than once via different fields, each occurrence will share the same field usage data because the underlying object is the same.

Sample output:

2019-03-03 15:02:41,727 [INFO] Displaying field usage for `MyModel object`:
2019-03-03 15:02:41,727 [INFO]   id: 5
2019-03-03 15:02:41,732 [INFO]   name: 1
2019-03-03 15:02:41,733 [INFO]   related_model: 1
2019-03-03 15:02:41,733 [INFO]     id: 1
2019-03-03 15:02:41,733 [INFO]     name: 1
2019-03-03 15:02:41,733 [INFO]   related_model_id: 1

If you are using custom metaclasses that inherit from the ModelBase class, you will need to combine your custom metaclass with the django_query_debug.mixins.FieldUsageTrackerMeta metaclass, and then extend the FieldUsageMixin mixin to use the new metaclass.

analyze_queryset

Provides a SQL explaination of a given queryset. In Django 2.1+, this is a wrapper method around the .explain() method of the queryset.

Sample usage:

from django_query_debug.utils import analyze_queryset

analyze_queryset(Model.objets.all())

analyze_block

A context manager that outputs debug information on all queries executed within that block of code. Outputs details such as the SQL statement, query time, number of results, number of query duplications, and the total time taken to execute the block of code divided between DB queries and everything else. The DEBUG setting must be set to True for Django to track queries.

Sample usage:

from django_query_debug.utils import analyze_block

with analyze_block():
  list(Model.objets.all())

Sample output:

2019-03-03 15:38:10,739 [INFO] ------------------------------------------------------------
2019-03-03 15:38:10,740 [INFO] Query 0 summary
2019-03-03 15:38:11,014 [INFO] SQL Statement:
SELECT "mock_models_simplerelatedmodel"."id",
       "mock_models_simplerelatedmodel"."name",
       "mock_models_simplerelatedmodel"."related_model_id",
       "mock_models_simplerelatedmodel"."one_to_one_model_id"
FROM "mock_models_simplerelatedmodel"
WHERE "mock_models_simplerelatedmodel"."name" = 'Test 2'

2019-03-03 15:38:11,015 [INFO] Query time: 0.0s
2019-03-03 15:38:11,015 [INFO] Number of results: 1
2019-03-03 15:38:11,015 [INFO] ------------------------------------------------------------
2019-03-03 15:38:11,016 [INFO] Query 1 summary
2019-03-03 15:38:11,021 [INFO] SQL Statement:
SELECT "mock_models_simplerelatedmodel"."id",
       "mock_models_simplerelatedmodel"."name",
       "mock_models_simplerelatedmodel"."related_model_id",
       "mock_models_simplerelatedmodel"."one_to_one_model_id"
FROM "mock_models_simplerelatedmodel"

2019-03-03 15:38:11,021 [INFO] Query time: 0.0s
2019-03-03 15:38:11,022 [INFO] Number of results: 2
2019-03-03 15:38:11,022 [INFO] Duplicated 2 times
2019-03-03 15:38:11,022 [INFO] ------------------------------------------------------------
2019-03-03 15:38:11,022 [INFO] Query 2 summary
2019-03-03 15:38:11,028 [INFO] SQL Statement:
SELECT "mock_models_simplemodel"."id",
       "mock_models_simplemodel"."name"
FROM "mock_models_simplemodel"
WHERE "mock_models_simplemodel"."id" = 1

2019-03-03 15:38:11,029 [INFO] Query time: 0.0s
2019-03-03 15:38:11,029 [INFO] Number of results: 1
2019-03-03 15:38:11,029 [INFO] ============================================================
2019-03-03 15:38:11,029 [INFO] Elapsed time: 0.00437188148499s
2019-03-03 15:38:11,029 [INFO] Time spent querying: 0.0s (0.0%)
2019-03-03 15:38:11,030 [INFO] Time spent otherwise: 0.00437188148499s (100.0%)
2019-03-03 15:38:11,030 [INFO] Query count: 4
2019-03-03 15:38:11,030 [INFO] Duplicate query count: 1
2019-03-03 15:38:11,030 [INFO] Total objects fetched: 6

Logging

All logs are sent to the query_debug logger. To enable stack traces with the query warnings, set the debug level to DEBUG.

Sample Configuration:

LOGGING = {
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'query_debug': {
            'handlers': ['console'],
            'level': 'DEBUG',
        }
    }
}

Django Settings:

Setting Default Description
ENABLE_QUERY_WARNINGS False Enable warnings for access to unprefetched model fields.

Development

After checking out repository, install using python setup.py develop.

To run tests, use python setup.py test.

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_query_debug-1.0.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

django_query_debug-1.0.0-py2.py3-none-any.whl (10.8 kB view details)

Uploaded Python 2Python 3

File details

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

File metadata

  • Download URL: django_query_debug-1.0.0.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.7.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.5

File hashes

Hashes for django_query_debug-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a689b697913e4a1826c910452a0ca7735dc6f765f77efef6d3f983df3e6f3496
MD5 ea1449c478897eefbce6d206a1e34db7
BLAKE2b-256 642f0128aecce908d7eaa9d1e260555a53211e33d44a66f76a2fbcd510368adc

See more details on using hashes here.

File details

Details for the file django_query_debug-1.0.0-py2.py3-none-any.whl.

File metadata

  • Download URL: django_query_debug-1.0.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 10.8 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.7.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.5

File hashes

Hashes for django_query_debug-1.0.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 a80936b783aea3d0bae72054a265622fb6217b558406ec80f80978da4127d384
MD5 9a7017d4fe3cb6c5fc1707b1249ef778
BLAKE2b-256 9eebb6a4acb7df1c7ed29dc72f6dd3470b85047f8d2c7157154c7402003f5b9f

See more details on using hashes here.

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