Package: django-query-debug
A Django application containing helper methods and mixins for debugging query issues.InstallationInstall package usingpip install django-query-debug.To use this package in an existing Django application, adddjango_query_debugtoINSTALLED_APPSin your settings file.Example:INSTALLED_APPS=['django_query_debug',...]UsagePatchDjangoDescriptorsMonkey 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 toDEBUG, a stack trace will be logged to help find the line that is causing the query.Sample usage:fromdjango_query_debug.patchimportPatchDjangoDescriptorsPatchDjangoDescriptors()FieldUsageMixinA 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 DjangoModelclass.
It will wrap all model fields in that class with a custom descriptor that tracks access attempts.Sample usage:fromdjango.dbimportmodelsfromdjango_query_debug.mixinsimportFieldUsageMixinclassMyModel(FieldUsageMixin,models.Model):name=models.CharField(max_length=255)related_model=models.ForeignKey(...)Callingdisplay_field_usage()on the model will log the output field usage data.
Field usage data for any related model that inherits fromFieldUsageMixinwill also be displayed.
To exclude data from related models, usedisplay_field_usage(show_related=False).
To reset field usage data, callreset_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-0315:02:41,727[INFO]Displayingfieldusagefor`MyModelobject`:2019-03-0315:02:41,727[INFO]id:52019-03-0315:02:41,732[INFO]name:12019-03-0315:02:41,733[INFO]related_model:12019-03-0315:02:41,733[INFO]id:12019-03-0315:02:41,733[INFO]name:12019-03-0315:02:41,733[INFO]related_model_id:1If you are using custom metaclasses that inherit from theModelBaseclass, you will need to
combine your custom metaclass with thedjango_query_debug.mixins.FieldUsageTrackerMetametaclass,
and then extend theFieldUsageMixinmixin to use the new metaclass.analyze_querysetProvides 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:fromdjango_query_debug.utilsimportanalyze_querysetanalyze_queryset(Model.objets.all())analyze_blockA 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.
TheDEBUGsetting must be set to True for Django to track queries.Sample usage:fromdjango_query_debug.utilsimportanalyze_blockwithanalyze_block():list(Model.objets.all())Sample output:2019-03-0315:38:10,739[INFO]------------------------------------------------------------2019-03-0315:38:10,740[INFO]Query0summary2019-03-0315:38:11,014[INFO]SQLStatement:
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-0315:38:11,015[INFO]Querytime:0.0s2019-03-0315:38:11,015[INFO]Numberofresults:12019-03-0315:38:11,015[INFO]------------------------------------------------------------2019-03-0315:38:11,016[INFO]Query1summary2019-03-0315:38:11,021[INFO]SQLStatement:
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-0315:38:11,021[INFO]Querytime:0.0s2019-03-0315:38:11,022[INFO]Numberofresults:22019-03-0315:38:11,022[INFO]Duplicated2times2019-03-0315:38:11,022[INFO]------------------------------------------------------------2019-03-0315:38:11,022[INFO]Query2summary2019-03-0315:38:11,028[INFO]SQLStatement:
SELECT"mock_models_simplemodel"."id","mock_models_simplemodel"."name"FROM"mock_models_simplemodel"WHERE"mock_models_simplemodel"."id"=12019-03-0315:38:11,029[INFO]Querytime:0.0s2019-03-0315:38:11,029[INFO]Numberofresults:12019-03-0315:38:11,029[INFO]============================================================2019-03-0315:38:11,029[INFO]Elapsedtime:0.00437188148499s2019-03-0315:38:11,029[INFO]Timespentquerying:0.0s(0.0%)2019-03-0315:38:11,030[INFO]Timespentotherwise:0.00437188148499s(100.0%)2019-03-0315:38:11,030[INFO]Querycount:42019-03-0315:38:11,030[INFO]Duplicatequerycount:12019-03-0315:38:11,030[INFO]Totalobjectsfetched:6LoggingAll logs are sent to thequery_debuglogger. To enable stack traces with the query warnings, set the debug level toDEBUG.Sample Configuration:LOGGING={'handlers':{'console':{'level':'DEBUG','class':'logging.StreamHandler',}},'loggers':{'query_debug':{'handlers':['console'],'level':'DEBUG',}}}Django Settings:SettingDefaultDescriptionENABLE_QUERY_WARNINGSFalseEnable warnings for access to unprefetched model fields.DevelopmentAfter checking out repository, install usingpython setup.py develop.To run tests, usepython setup.py test.