Django/Postgres:在 RangeField 上聚合
Posted
技术标签:
【中文标题】Django/Postgres:在 RangeField 上聚合【英文标题】:Django/Postgres: Aggregate on RangeField 【发布时间】:2018-12-16 20:21:22 【问题描述】:是否可以对Django
的RangeField
进行聚合函数?
假设我们有 3 个对象,BigIntegerField
price_range
。
第一个对象:price_range = [10,5000]
第二个对象:price_range = [1,5000]
第三个对象:price_range = [100,9000]
Max
和Min
这三个对象的聚合结果将是:
min = 1
和 max = 9000
我正在尝试以这种方式聚合 Max
和 Min
:
MyModel.objects.aggregate(Min('price_range'),Max('price_range'),)
这会引发错误:
ProgrammingError: 函数 min(int8range) 不存在第 1 行: SELECT MIN("app_mymodel"."price_range") AS "price_range__min" FROM "app...
【问题讨论】:
如果两者不重叠怎么办?喜欢[1, 5]
和[8, 10]
?
@WillemVanOnsem 没关系。我想得到最低下限和最高上限。
【参考方案1】:
您可以使用Upper(..)
和Lower(..)
获得范围界限,所以:
from django.db.models.functions import Upper, Lower
MyModel.objects.aggregate(Min(Lower('price_range')), Max(Upper('price_range')))
但请注意,如果范围不重叠(例如 [0, 20]
和 [50, 100]
),您仍然会得到一个范围 [0, 100]
。
显然现代版本的 Django 需要将字段命名为 @EricTheise says:
from django.db.models.functions import Upper, Lower
MyModel.objects.aggregate(
low=Min(Lower('price_range')),
high=Max(Upper('price_range'))
)
【讨论】:
是的,这正是我想要的。它用于过滤目的。谢谢 感谢几年后遇到这个答案,Django (3.0.6) 给了我一个TypeError: Complex expressions require an alias
。在this answer 的指导下,我需要做相当于MyModel.objects.aggregate(lower=Min(Lower('price_range')), upper=Max(Upper('price_range')))
以上是关于Django/Postgres:在 RangeField 上聚合的主要内容,如果未能解决你的问题,请参考以下文章
Django + Postgres:将 JSON 字符串作为 JSON 类型直接保存到模型中
Django Postgres objects.create ValidationError
django、postgres 8.4、psycopg 2.2.2、python 2.7、mod_wsgi