In Django Queryset, is there a way to update objects by group that are formed by group_by(annotations)?

Viewed 29

My specific example:

class AggregatedResult(models.Model) :        
    amount = models.IntegerField()
    
class RawResult(models.Model) :
    
    aggregate_result = models.ForeignKey(AggregatedResult, ...)
    type = models.CharField()
    date = models.DateField()
    amount = models.IntegerField()

In this specific example RawResults have different type and date, and I'd like to make a queryset to aggregate them. so for example, I'd do something like :

RawResults.objects.values("type","date").annotate(amount_sum = Sum("amount"))

Then I'd create AggregatedResult objects based off the results.

Problem here is I have a ForeignKey relationship to AggregatedResult and I would like to assign proper foreignkey to RawResult, base off which objects have contributed to which result.

For instance, assume:

RawResult
idx type date amount
1   A    10-04    10
2   A    10-04     8
3   A    10-05     7
4   B    10-04     5

Running the queryset above will give me aggregated values, however, I want to update RawResult objects to be properly mapped to AggregatedResult. So like:

[
  {A, 10-04, 18}  AggregatedResult(1)  <- RawResult 1,2 should have aggregate_result = 1
  {A, 10-05, 7}   AggregatedResult(2)  <- RawResult 3 should have aggregate_result = 2
  {B, 10-04, 5}   AggregatedResult(3)  <- RawResult 4 should have aggregate_result = 3
]

I have moderate size of RawResult(500k ish), and little types (~15 types), and the aggregated result is expected to yield about ~5 different dates, which gives me about ~75 groups(and thus AggregatedResult) whenever I run this task.

I understand that I can drop group_by(values_annotate) entirely, and run something like distinct) then run ~75 different filter queries based off type-date combinations. I personally think this is probably questionable since I'd have to run this task multiple times (ex. per user).

Is there a better way to solve this?

0 Answers
Related