Home > Mobile >  Django - Aggregate into array
Django - Aggregate into array

Time:10-19

I use SQLite and have a django model with the below data:

Name Value
A 1
B 2
B 4
C 7
C 5

I would like to use an aggregate my table so that I can get my data in the below format:

Name Value
A 1
B [2,4]
C [7,5]

How do I do this with Django.

I'm thinking this may be the answer but Django doesn't seem to have ArrayAgg. This looks to be a PostgreSQL function

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

Do you know how I can achieve this without using PostgreSQL? Thank you!

CodePudding user response:

For PostgreSQL, Django has an ArrayAgg function [Django-doc]:

from django.contrib.postgres.aggregates import ArrayAgg

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

CodePudding user response:

You can use groupby from itertools , then create the aggregate for any databases:

>>> 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]}]

CodePudding user response:

First create your own aggregate like this

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)

After creating this use below query

Test_Model.objects.values('name').annotate(dname=GroupConcat('value')).order_by('name')
  • Related