Improved API for aggregating using Subquery
Project description
Django SQL Utils
This package provides utilities for working with Django querysets so that you can generate the SQL that you want, with an API you enjoy.
Subquery Aggregates
The Count aggregation in Django:
Parent.objects.annotate(child_count=Count('child'))
generates SQL like the following:
SELECT parent.*, Count(child.id) as child_count FROM parent JOIN child on child.parent_id = parent.id GROUP BY parent.id
In many cases, this is not as performant as doing the count in a SUBQUERY instead of with a JOIN:
SELECT parent.*, (SELECT Count(id) FROM child WHERE parent_id = parent.id) as child_count FROM parent
Django allows us to generate this SQL using The Subquery and OuterRef classes:
subquery = Subquery(Child.objects.filter(parent_id=OuterRef('id')).order_by() .values('parent').annotate(count=Count('pk')) .values('count'), output_field=IntegerField()) Parent.objects.annotate(child_count=Coalesce(subquery, 0))
Holy cow! It’s not trivial to figure what everything is doing in the above code and it’s not particularly good for maintenance. SubqueryAggregates allow you to forget all that complexity and generate the subquery count like this:
Parent.objects.annotate(child_count=SubqueryCount('child'))
Phew! Much easier to read and understand. It’s the same API as the original Count just specifying the Subquery version.
In addition to SubqueryCount, this package provides SubqueryMin and SubqueryMax. If you want to use other aggregates, you can use the generic SubqueryAggregate class:
from django.db.models import Avg, DecimalField aggregate = SubqueryAggregate('child__age', aggregate=Avg, output_field=DecimalField()) Parent.objects.annotate(avg_child_age=aggregate)
Or subclass SubqueryAggregate:
from django.db.models import Avg class SubqueryAvg(SubqueryAggregate) aggregate = Avg unordered = True Parent.objects.annotate(avg_child_age=SubqueryAvg('child__age')
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
File details
Details for the file django-sql-utils-0.1.1.tar.gz
.
File metadata
- Download URL: django-sql-utils-0.1.1.tar.gz
- Upload date:
- Size: 6.7 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.6.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e6e6277bc2c89eb617d7e5665b6898d858ed98cdfe09e1bfcaff8c55246da3d6 |
|
MD5 | 0476077fd9186359e8d5458a722d65af |
|
BLAKE2b-256 | d05411cc7195efe20b08a862c44594aad6e67e4aa15b0175ee923edcc2a1129d |
File details
Details for the file django_sql_utils-0.1.1-py3-none-any.whl
.
File metadata
- Download URL: django_sql_utils-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ba11c283977be595bc657581ea450dadf33dada4e66b1447b20f8e23fd94134d |
|
MD5 | 4622c6028e9c0636c9f77a44ed36e913 |
|
BLAKE2b-256 | f8dac78747478c9b2a4e2d16ed954bed72d5fcb768bf1314780b4eefcd1abb95 |