My previous version had a bug, the use of "min"
The following, using "Least()" instead of min() seems to have resolved that

    clusters = nodes.values('cluster').annotate(

        count_left=Least(F('cluster__volume_limit') - F(
'cluster__volume_count'),

                         Sum(F('volume_limit') - F('volume_count'))),

        size_left=Least(F('cluster__size_limit') - F('cluster__volume_size'
),

                        Sum(F('size_limit') - F('volume_size')))).distinct()

    node_counts = clusters.aggregate(Sum('count_left'), Sum('size_left'))

On Saturday, July 1, 2017 at 7:34:37 PM UTC-7, sarvi wrote:
>
> A further bit of clarification
>
> clusters = nodes.values('cluster').annotate(count_left=min(F(
> 'cluster__volume_limit') - F('cluster__volume_count'),
>
>                                                            Sum(F(
> 'volume_limit') - F('volume_count'))),
>
>                                             size_left=min(F(
> 'cluster__size_limit') - F('cluster__volume_size'),
>
>                                                           Sum(F(
> 'size_limit') - F('volume_size'))))
>
>
> produced duplicate entries as
>
> <QuerySet [{'cluster': 1, 'size_left': 1960, 'count_left': 18}, 
> {'cluster': 1, 'size_left': 1960, 'count_left': 18}, {'cluster': 2, 
> 'size_left': 2000, 'count_left': 20}, {'cluster': 2, 'size_left': 2000, 
> 'count_left': 20}]>
>
>
>
> Using distinct()  remove duplicates as follows
>
> clusters = nodes.values('cluster').annotate(count_left=min(F(
> 'cluster__volume_limit') - F('cluster__volume_count'),
>
>                                                            Sum(F(
> 'volume_limit') - F('volume_count'))),
>
>                                             size_left=min(F(
> 'cluster__size_limit') - F('cluster__volume_size'),
>
>                                                           Sum(F(
> 'size_limit') - F('volume_size')))).distinct()
>
> <QuerySet [{'cluster': 1, 'size_left': 1960, 'count_left': 18}, 
> {'cluster': 2, 'size_left': 2000, 'count_left': 20}]>
>
>
> But am not sure If that I am doing this appropriately.
>
>
> Sarvi
>
> On Saturday, July 1, 2017 at 5:59:41 PM UTC-7, sarvi wrote:
>>
>> This seems to work
>> Node.objects.values('cluster').annotate(volume_left=min(F('cluster__volume_limit')-F('cluster__volume_count'),
>>  
>> Sum(F('volume_limit')-F('volume_count'))))
>>
>> <QuerySet [{'cluster': 1, 'volume_left': 8}, {'cluster': 1, 
>> 'volume_left': 8}, {'cluster': 2, 'volume_left': 20}, {'cluster': 2, 
>> 'volume_left': 20}]>
>>
>>
>> Do I have it right? Just wanted to confirm.
>>
>> Thanks
>>
>>
>> On Saturday, July 1, 2017 at 5:41:20 PM UTC-7, sarvi wrote:
>>>
>>>
>>> Django Verion:  1.11.1
>>>
>>> My models
>>>
>>> class Cluster(models.Model):
>>>
>>> ....
>>>
>>>     volume_limit = models.IntegerField('Cluster Volume Count Limit')
>>>
>>>     volume_count = models.IntegerField('Cluster Volume Count', default=0
>>> )
>>>
>>> ....
>>>
>>>
>>> class Node(models.Model):
>>>
>>>     cluster = models.ForeignKey(Cluster, related_name='cluster_nodes', 
>>> on_delete=models.PROTECT)
>>>
>>>     volume_limit = models.IntegerField('Node Volume Count Limit')
>>>
>>>     volume_count = models.IntegerField('Node Volume Count', default=0)
>>>
>>>
>>> My query
>>>
>>> nodes = Node.objects.filter(....)
>>>
>>> intermediatestep = 
>>> nodes.objects.annotate(volume_left=F('volume_limit')-F('volume_count')).values('cluster__id').annotate(cluster_volume_left_sum=
>>> Sum('volume_left'))
>>>
>>>
>>> Error:
>>>
>>>   File 
>>> "/Users/sarvi/virtenv/toothless/lib/python2.7/site-packages/django/db/models/expressions.py",
>>>  
>>> line 471, in resolve_expression
>>>
>>>     return query.resolve_ref(self.name, allow_joins, reuse, summarize)
>>>
>>>   File 
>>> "/Users/sarvi/virtenv/toothless/lib/python2.7/site-packages/django/db/models/sql/query.py",
>>>  
>>> line 1481, in resolve_ref
>>>
>>>     return Ref(name, self.annotation_select[name])
>>>
>>> KeyError: 'volume_left'
>>>
>>>
>>> My ultimate Goal: 
>>>
>>>     What I am trying to achieve is to get from a
>>>
>>>     1. filtered query of Nodes, to calculate 
>>> volume_left=F('volume_limit')-F('volume_count') for each node
>>>
>>>     2. then group by cluster and sum up what volume_left in each node to 
>>> cluster_volume_left_sum for each cluster. 
>>>
>>>     3. Then get a cluster level 
>>> cluster_volume_left=F('volume_limit')-F('volume_count'),
>>>
>>>     4. Then calculate at the cluster level Min(0, 
>>> F('cluster_volume_left')-F('volume_left__sum'))
>>>
>>>
>>> I am obviously stuck way earlier :-)
>>>
>>>
>>> From what I read of the documentation and Stackoverflow this should be 
>>> possible
>>>
>>>
>>> Any pointer on what I am doing wrong here would be of great help.
>>>
>>>
>>> Thanks,
>>>
>>> Sarvi
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/b335311d-e23a-4e6e-bca4-23e2f379e75d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to