#32663: Remove Error raising on annotation & distinct call
-------------------------------------+-------------------------------------
               Reporter:  Yovel      |          Owner:  nobody
  Cohen                              |
                   Type:             |         Status:  new
  Cleanup/optimization               |
              Component:  Database   |        Version:  3.2
  layer (models, ORM)                |       Keywords:  SQLCompiler ORM
               Severity:  Normal     |  Query
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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)
 ```
 adding the following distinct calls all 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>
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/053.2150307c7ef8a8eb5cb389eb7ff56d9f%40djangoproject.com.

Reply via email to