django-sql-utils

raw JSON →
0.7.0 verified Mon Apr 27 auth: no python maintenance

Improved API for aggregating using Subquery in Django. Provides SubqueryAggregate, SubqueryCount, SubquerySum, etc. Current version 0.7.0, supports Django 1.11 to 3.0+. Maintenance frequency: irregular, last release 2020.

pip install django-sql-utils
error ImportError: No module named 'sql_util'
cause Package not installed or wrong import name.
fix
Run: pip install django-sql-utils
error django.core.exceptions.FieldError: Cannot resolve keyword 'author_id' into field. Choices are: ...
cause Using the database column name (e.g., 'author_id') instead of the relation name (e.g., 'author') in SubqueryAggregate.
fix
Use the field name without '_id', e.g., SubqueryCount('author') instead of SubqueryCount('author_id')
error AttributeError: 'SubqueryAggregate' object has no attribute 'resolve_expression'
cause Using an older version of Django (<1.11) or incompatible Django version.
fix
Upgrade Django to at least 1.11. If using Django 3.2+, consider using Django's built-in Subquery.
gotcha Aggregating over ForeignKey IDs fails if the FK column name differs from the related model's default id column. Use the related field name (e.g., 'author') not the column name.
fix Use SubqueryCount('author') instead of SubqueryCount('author_id') or SubqueryCount('author__id').
breaking Requires Python >=3.8 and Django >=1.11. No official support for Django 4.0+ or Python 3.11+. May break with newer Django versions.
fix Test thoroughly with your Django version. Consider switching to Django's built-in Subquery() and annotate() if using Django 3.0+.
deprecated The package is no longer actively maintained. Last release 2020. For Django 3.2+ you may not need this library; Django's Subquery expressions now cover most use cases.
fix Migrate to Django's annotate() with Subquery() and OuterRef().
gotcha When using update(), SubqueryAggregate may raise an error if related_name and related_query_name differ on ForeignKey. Fixed in 0.7.0 but still fragile.
fix Upgrade to 0.7.0 or ensure related_name and related_query_name match.

Replace 'myapp.models' with your actual app/models. The SubqueryAggregate family works like Django's aggregates but generates subqueries.

from sql_util import SubqueryCount, SubquerySum
from myapp.models import Author, Book

# Annotate each author with count of books
qs = Author.objects.annotate(
    book_count=SubqueryCount('book')
)

# Annotate each author with total price of books where price > 10
from django.db.models import Q
qs = Author.objects.annotate(
    expensive_total=SubquerySum('book__price', filter=Q(book__price__gt=10))
)

# Use with updates (Django 2.0+)
Author.objects.update(
    book_count=SubqueryCount('book')
)