Opened 5 years ago

Last modified 4 years ago

#30188 closed Bug

Aggregate annotation, Case() - When(): AssertionError No exception message supplied — at Version 1

Reported by: Lukas Klement Owned by: nobody
Component: Database layer (models, ORM) Version: 2.1
Severity: Normal Keywords: query, aggregate, case/when
Cc: Can Sarıgöl, Simon Charette Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description (last modified by Lukas Klement)

Aggregating annotations works for simple Sum, Count, etc. operations, but fails when the Sum() contains a Case() When() operation.

Example:
Objective: sum the number of None values for the annotated field field_name across a queryset.

field_name = <name of annotated field>
missing_data_agg=Sum(
    Case(
            When(**{field_name: None}, then=Value(1)),
            default=Value(0),
            output_field=IntegerField()
    )
)

Expected behaviour: calling queryset.aggregate(missing_data=missing_data_agg) returns a dict {'missing_data': <value>}
Actual behaviour: AssertionError No exception message supplied is returned.

When field_name is set to a field that exists on the model of the queryset, the aggregation works. When field_name is set to a field that is neither in the model of the queryset, nor has it been annotated to the queryset, the exception returned is as expected: Cannot resolve keyword <name of the non existing field> into field . Choices are: <list of model and annotated fields. In this list, the field_name that has been annotated to the queryset is shown -> hence it should work, hence I assume this is a Django bug.

Stacktrace:

<Line with the .aggregate(...)>
        return query.get_aggregation(self.db, kwargs) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in get_aggregation
                    expression, col_cnt = inner_query.rewrite_cols(expression, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/sql/query.py in rewrite_cols
        annotation.set_source_expressions(new_exprs) ...
/Users/{{path}}/lib/python3.6/site-packages/django/db/models/expressions.py in set_source_expressions
        assert not exprs 

The database is a PostgreSQL database, the Django version is 2.1.7, the Python version is 3.6.4. The problem also exists under Django version 2.2b1

Change History (1)

comment:1 by Lukas Klement, 5 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top