Django -聚合到数组中

jjhzyzn0  于 2021-05-29  发布在  Go
关注(0)|答案(4)|浏览(155)

我使用SQLite,有一个django模型,数据如下:
| 姓名|价值|
| - ------|- ------|
| A类|1个|
| B|第二章|
| B|四个|
| C级|七|
| C级|五个|
我想使用一个聚合我的表,这样我就可以得到我的数据在下面的格式:
| 姓名|价值|
| - ------|- ------|
| A类|1个|
| B|[二、四]|
| C级|[七、五]|
我该怎么对付 Django 。
我想这可能是答案,但Django似乎没有ArrayAgg。这看起来是一个PostgreSQL函数

Test_Model.objects.annotate(dname=ArrayAgg('name')).values()

你知道不使用PostgreSQL我怎么能做到这一点吗?谢谢!

7xllpg7q

7xllpg7q1#

您可以使用itertools中的groupby,然后为任何数据库创建聚合:

>>> from itertools import groupby
>>> [{'Name': key, 'Value': list(item.Value for item in grp)} for key, grp in
    groupby(Test_Model.objects.order_by('Name'), key=lambda x: x.Name)]
[{'Name': 'A', 'Value': [1]},
 {'Name': 'B', 'Value': [2, 4]},
 {'Name': 'C', 'Value': [7, 5]}]
1cklez4t

1cklez4t2#

对于 PostgreSQL,Django有一个**ArrayAgg**函数[Django-doc]:

from django.contrib.postgres.aggregates import ArrayAgg

Test_Model.objects.values('name').annotate(dname=ArrayAgg('value')).order_by('name')
juud5qan

juud5qan3#

首先像这样创建自己的聚合

from django.db.models import Aggregate

class GroupConcat(Aggregate):
    function = 'GROUP_CONCAT'
    template = '%(function)s(%(distinct)s%(expressions)s)'

    def __init__(self, expression, distinct=False, **extra):
        super(GroupConcat, self).__init__(
            expression,
            distinct='DISTINCT ' if distinct else '',
            output_field=CharField(),
            **extra)

创建后,使用以下查询

Test_Model.objects.values('name').annotate(dname=GroupConcat('value')).order_by('name')
0wi1tuuw

0wi1tuuw4#

基于@deepak-tripathi的answer,他们的解决方案返回一个字符串,使用SQLite的JSON_GROUP_ARRAY聚合函数和Django的JSONField返回一个列表:

class JsonGroupArray(Aggregate):
    function = 'JSON_GROUP_ARRAY'
    output_field = JSONField()
    template = '%(function)s(%(distinct)s%(expressions)s)'

(Don'实际上并不需要覆盖的__init__(),除非你想要DISTINCT的功能,在这种情况下也可以只使用allow_distinct=True
然后就像@deepak-tripathi说的那样,使用它:

Test_Model.objects.values('name').annotate(dname=JsonGroupArray('value')).order_by('name')

相关问题