django - 获取 Django 查询集中所有字段的总和
问题描述
我正在尝试对查询集中的记录中的字段求和。我基本上想要每个字段的总和。
我这样做如下:
field_names = MyModel._meta.get_fields()
queryset = MyModel.objects.filter(some filter criteria)
for fn in field_names:
result = queryset.aggregate(Sum(fn.name))
actual = result[fn.name+'__sum']
这显然是非常低效的。我如何有效地做到这一点?
解决方案
效率低下可能是由于您对每一列都执行查询。作为 20 个字段的结果,您执行 20 个查询。
进行查询通常是昂贵的,并且大量类型是“独立于查询”的,因为它需要时间,无论查询本身应该做什么:需要创建查询,将其传递给数据库,然后数据库需要提出一个“查询执行计划”,然后执行查询,并将响应传回。当然,查询本身需要一些时间,但正如您所见,每个查询还需要运行其他一些任务。因此,即使查询非常便宜,它们也会消耗大量资源。但是,如果过滤也很重要(不是可以通过索引轻松解决的问题),我们还会做很多重复的工作来确定要考虑表的哪些行。
您可以通过首先使用列表理解,然后将其传递为*args
:
result = queryset.aggregate(*[Sum(fn.name) for fn in field_names])
现在result
是一个字典,将所有这些字段映射到它们相应的总和,例如:
# example result
result == { 'foo__sum': 42, 'bar__sum': 14, 'qux__sum': 52 }
因此,查询将如下所示:
SELECT SUM(foo) AS foo__sum, SUM(bar) AS bar__sum, SUM(qux) AS qux__sum
FROM mymodel
WHERE 1 = 1 -- some filter conditions
因此,所有聚合都在同一个查询中计算。
注意:由于
field_names
是字段的集合,而不是字段的名称,我建议将此变量重命名为fields
,以避免以后出现任何混淆。
推荐阅读
- python - 抽样分布正态近似不拟合
- rust - 切片的安全 memset 相当于什么?
- react-day-picker - react-day-picker DayPickerInput 未触发 onDayChange 事件
- firebase - 如何使用 vue.js 将简单数据保存在 firebase 中?
- java - IBM java8 BigDecimal 浮动问题与 MathContext.DECIMAL64
- python - 这个 python 概念叫什么?使用子属性的父类。
- bash - 字符串同时大于零且为空
- c# - 在 VSTO 中,如何从 Excel 中的表中删除行
- c++ - QT Quick/QML 是否能够加载用户定义的插件?
- java - 如何在百里香中将形式拆分成碎片?