question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple calls to annotate returns only latest annotation when calling select_subclasses.

See original GitHub issue

Problem

When making chained calls to annotate() on a single queryset, only the last annotation applied is returned after calling select_subclasses. If you don’t call select_subclasses, you do receive all annotations.

Environment

  • Django Model Utils version: 3.1.1
  • Django version: 2.0
  • Python version: 3.5.2
  • Other libraries used, if any: n/a

Code examples

In the sample below, the only annotation that is available in the evaluated queryset is correct_count.

import django
django.setup()  # noqa

from django.db.models import Case, When, ExpressionWrapper, FloatField, Sum, Q

from sampleapp import models

correct_count_calc = ExpressionWrapper(
    Sum(
        Case(
            When((Q(answer__correct=True) & Q(answer__quizresult__user__is_superuser=False)), then=1),
            default=0
        )
    ), FloatField()
)

answered_count_calc = ExpressionWrapper(
    Sum(
        Case(
            When(answer__quizresult__user__is_superuser=False, then=1.0),
            default=0
        )
    ), FloatField()
)

q = models.BaseQuestion.objects.annotate(answered_count=answered_count_calc) \
                               .annotate(correct_count=correct_count_calc).select_subclasses().first()
print(q.__dict__)

It seems the problem stems from the snippet below, which sets (rather than appending to) the qset._annotated value for each subsequent call to .annotate().

https://github.com/jazzband/django-model-utils/blob/1eff6d0d8f5e880db63493b59126a448a30a74e1/model_utils/managers.py#L116

I have a simple fix for this issue here:

https://github.com/digismack/django-model-utils/commit/6a72cebfc02fd19e68c15343fa9647256ad1e0f9

I was unable to get the test suite to run. They all fail with AppRegistryNotReady: Apps aren't loaded yet. If someone would be willing to help me out a bit, I’d love to submit a pull request with tests and such.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:2
  • Comments:6

github_iconTop GitHub Comments

3reactions
kltchnkocommented, Aug 13, 2021

@areyal @digismack Thank you for finding out this issue and possible solutions! I slightly changed the code and it worked (Django==3.1.7, django-model-utils==4.1.1)! You don’t need to fork this repo, just subclass from django.db.models.QuerySet and add InheritanceQuerySetMixin.

class FixedInheritanceQuerySet(InheritanceQuerySetMixin, QuerySet):
    def annotate(self, *args, **kwargs):
        qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs)
        annlist = [a.default_alias for a in args] + list(kwargs.keys())
        if not hasattr(qset, '_annotated'):
            qset._annotated = annlist
        else:
            qset._annotated.extend(a for a in annlist if a not in qset._annotated)
        return qset
1reaction
digismackcommented, Jan 31, 2018

@tony Maybe you can take a look at this and let me know what you think?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Django annotate() multiple times causes wrong answers
Django has the great new annotate() function for querysets. However I can't get it to work properly for multiple annotations in a single...
Read more >
Add annotations and metadata to segments with the X-Ray ...
To record annotations, call AddAnnotation with a string containing the metadata you want to associate with the segment. xray.AddAnnotation( key string ...
Read more >
Index (OpenJPA 1.1.0 API) - Oracle Help Center
ClassMetaData: Adds fetch group of the given name, or returns existing instance. ... VersionStrategy: This method is called after data is loaded into...
Read more >
Is there a way to annotate the return types of a function that ...
But a type annotation would also be valid as an input type and using ... If it returns multiple values at the same...
Read more >
The Chemical Space Project - ACS Publications
The so-called “drug-like” chemical space has been estimated at 10 60 ... 322 compounds from GDB-13 also annotated as nicotinic acetylcholine ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found