#33477: Union Operator merges annotated values wrongfully
-------------------------------------+-------------------------------------
               Reporter:  Tobias     |          Owner:  nobody
  Maschek                            |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  4.0
  layer (models, ORM)                |       Keywords:  annotation,
               Severity:  Normal     |  querysets, merging
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Hi, maybe I'm doing something majorly incorrectly, but Django merges
 Querysets at least in an unexpected way.

 = Setup
 I have the following models:
 {{{
 class Employee(models.Model):
     name = models.CharField(max_length=64)

 class Shift(models.Model):
     employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
     start = models.DateTimeField()
     dur = models.DecimalField(max_digits=4, decimal_places=2, default=0)
 }}}

 = Querysets
 With
 {{{ employees_with_shifts =
 Employee.objects.filter(shift__start__range=(monday, monday +
 timedelta(weeks=1))).annotate(total=Sum('shift__dur')) }}}
 I can get all employees, that have at least one shift in the week
 containing the given monday, with the annotated total worktime.


 With
 {{{
 employees_without_shifts = Employee.objects.annotate(total=Value(0,
 IntegerField()))
     .exclude(shift__start__range=(monday, monday + timedelta(weeks=1)))
 }}}
 I get all employees without any shifts and on all objects is the total
 annotated with 0. So far, so good.

 = The Problem

 But if I'm now combining these two sets to `employees =
 employees_with_shifts | employees_without_shifts`, **the annotated total
 value is not any more zero** for all employees in
 `employees_without_shifts `, instead it's some sum of all shifts (ignoring
 the week). Even when the exclude statement is removed, it changes nothing.

 I suspect that Django combines these two Querysets before evaluating, and
 in the combination process the range gets thrown off.

 If I'm combining these two sets with `employees =
 sorted(chain(employees_with, employees_without), key=lambda instance:
 instance.id)` the annotated value is correct.

 Or do I use the union operator incorrectly?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33477>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/047.b4a1f02a857daf9ea04664cb7af45beb%40djangoproject.com.

Reply via email to