Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:在可变列数上注释sum_Python_Django_Django Annotate - Fatal编程技术网

Python Django:在可变列数上注释sum

Python Django:在可变列数上注释sum,python,django,django-annotate,Python,Django,Django Annotate,我已经阅读了注释列,并利用了F()函数,了解了如何对多个列求和。但是,我使用的是EAV样式的数据库,所以我得到了一个列的可变列表。考虑这个例子: class TestModel(models.Model): column_a = models.FloatField() column_b = models.FloatField() column_c = models.FloatField() column_d = models.FloatField() 尝试1:

我已经阅读了注释列,并利用了F()函数,了解了如何对多个列求和。但是,我使用的是EAV样式的数据库,所以我得到了一个列的可变列表。考虑这个例子:

class TestModel(models.Model):
    column_a = models.FloatField()
    column_b = models.FloatField()
    column_c = models.FloatField()
    column_d = models.FloatField()
尝试1:

columns = {'column_a', 'column_c', 'column_d'}
queryset = DummyModel.objects.annotate(total=Sum([F(column_name) for column_name in columns]))
queryset = DummyModel.objects.annotate(total=ExpressionWrapper(Sum([F(column_name) for column_name in columns]), output_field=FloatField())) 
但是,
print(queryset.query)
会产生错误
django.core.exceptions.FieldError:无法解析表达式类型,未知输出\u字段

尝试2:

columns = {'column_a', 'column_c', 'column_d'}
queryset = DummyModel.objects.annotate(total=Sum([F(column_name) for column_name in columns]))
queryset = DummyModel.objects.annotate(total=ExpressionWrapper(Sum([F(column_name) for column_name in columns]), output_field=FloatField())) 
这不会产生编译错误,但SQL查询会产生:

SELECT "test_model"."column_a", "test_model"."column_c", "test_model"."column_d", SUM([]) AS "total" FROM "test_model"

它是空的。有人知道如何解决这个问题吗?非常感谢您的帮助

要想弄清楚这一点,可以先画出表格:

column_a | column b | column_c
---------+----------+----------
1        | 2        | 3
4        | 5        | 6
7        | 8        | 9
Sum
是一种“垂直”操作;也就是说,如果我们想要
列a
的总和,我们可以这样做

>>> DummyModel.objects.aggregate(total=Sum('column_a'))
{'total': 12}
如您所见,这将返回
1+4+7==12
——因此您可以理解为什么我将其称为“垂直”和。请注意,我们使用的是
aggregate
而不是
annotate
aggregate
用于垂直运算符

相反,如果我们想要“水平”总和——一行中的总和——我们将使用
F()
+
。因此,要在每行中获得
列a+列b
,我们将使用

>>> DummyModel.objects.annotate(total=F('column_a') + F('column_b')).values('total')
<QuerySet [{'total': 3}, {'total': 9}, {'total': 15}]>
如果我们想要一个水平和一个垂直的总和——即
列a
的总和加上
列b
的总和——我们需要使用
F()

注意:
aggregate
而不是annotate,因为我们最终使用的是垂直操作;行的
总和。是的,首先有一个水平操作,但是因为我们最终需要
求和
,所以我们需要
聚合

因此,总而言之,如果字段是一个变量,我们需要结合
聚合
求和
,以及上面的
减少
技巧:

>>> cols = ['column_b', 'column_c']
>>> expr = reduce(add, (F(col) for col in cols))
>>> DummyModel.objects.aggregate(total=Sum(expr))
{'total': 33}

希望这有帮助

是的,这就是我要找的。实际上,我可以使用更简单的方法,甚至可以合法地使用python中的简单的
sum
F()
进行水平求和,以使其正常工作。使用
reduce
将更为通用,但对于我的使用目的来说并非必需。在任何情况下,我都不需要聚合,只需要动态水平求和。原来我很接近。谢谢