#32663: Remove Error raising on annotation & distinct call
-------------------------------------+-------------------------------------
Reporter: Yovel Cohen | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Database layer | Version: 3.2
(models, ORM) |
Severity: Normal | Resolution:
Keywords: SQLCompiler ORM | Triage Stage:
Query | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Yovel Cohen:
Old description:
> if you try to call distinct on an annotated query, it sometimes works,
> sometimes get's ignore, and sometimes raises an error.
> I had a query facing all three scenarios and solving the last one was the
> one that worked out.
>
> the error being raised is:
>
> {{{
> NotImplementedError: annotate() + distinct(fields) is not implemented.
>
> }}}
>
> after looking at the source code for the exception at
> django.db.models.sql.compiler.SQLCompiler
> row 594
>
> {{{
> if grouping:
> if distinct_fields:
> raise NotImplementedError('annotate() + distinct(fields) is
> not implemented.')
> order_by = order_by or self.connection.ops.force_no_ordering()
> result.append('GROUP BY %s' % ', '.join(grouping))
> # rest of the as_sql() method
>
> }}}
>
> after just removing the distinct_fields condition:
>
> {{{
> if grouping:
> order_by = order_by or self.connection.ops.force_no_ordering()
> result.append('GROUP BY %s' % ', '.join(grouping))
> # rest of the as_sql() method
> }}}
>
>
> it works, at least in the following ways I tried (annotations are just
> made up for sake of the example)
>
> {{{
>
> model_scores_latest_date_annotation = Max('model_scores__date')
> latest_score_annotation = Case(When(model_scores__date=F('latest_date'),
> then='model_scores__score')
> base_query_set = (Model.objects.
> filter(**filters).
> alias(latest_date=model_scores_latest_date_annotation).
> values(ID).
> annotate(latest_score=latest_score_annotation,
> latest_date=model_scores_latest_date_annotation)
> )
>
> }}}
>
> all the following distinct calls worked:
>
> {{{
>
> query_set = base_query_set.order_by('latest_date').distinct('id',
> 'latest_date')
>
> query_set = base_query_set.distinct('id')
>
> query_set = base_query_set.distinct('id', 'latest_date')
>
> }}}
>
> which makes me think that the as_sql method on SQLCompiler can handle
> more cases easily and this just fell beneath the cracks.
New description:
if you try to call distinct on an annotated query, it sometimes works,
sometimes get's ignore, and sometimes raises an error.
I had a query facing all three scenarios and solving the last one was the
one that worked out.
the error being raised is:
{{{
NotImplementedError: annotate() + distinct(fields) is not implemented.
}}}
after looking at the source code for the exception at
django.db.models.sql.compiler.SQLCompiler
row 594
{{{
if grouping:
if distinct_fields:
raise NotImplementedError('annotate() + distinct(fields) is not
implemented.')
order_by = order_by or self.connection.ops.force_no_ordering()
result.append('GROUP BY %s' % ', '.join(grouping))
# rest of the as_sql() method
}}}
after just removing the distinct_fields condition:
{{{
if grouping:
order_by = order_by or self.connection.ops.force_no_ordering()
result.append('GROUP BY %s' % ', '.join(grouping))
# rest of the as_sql() method
}}}
it works, at least in the following ways I tried (annotations are just
made up for sake of the example)
{{{
model_scores_latest_date_annotation = Max('model_scores__date')
latest_score_annotation = Case(When(model_scores__date=F('latest_date'),
then='model_scores__score')
base_query_set = base_query_set = (Model.objects.
filter(**filters).
alias(latest_date=model_scores_latest_date_annotation).
values(ID).
annotate(latest_score=latest_score_annotation,
latest_date=model_scores_latest_date_annotation)
)
}}}
all the following distinct calls worked:
{{{
query_set = base_query_set.order_by('latest_date').distinct('id',
'latest_date')
query_set = base_query_set.distinct('id')
query_set = base_query_set.distinct('id', 'latest_date')
}}}
which makes me think that the as_sql method on SQLCompiler can handle more
cases easily and this just fell beneath the cracks.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/32663#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/068.b5dee0081935d81d00a8e0caab475fc1%40djangoproject.com.