PostgreSQL에서 지원하는 array나 string 타입의 함수를 장고에서도 일부 지원을 합니다. 예를 들어, array 타입 함수의 unnest나 여러 row를 array로 변형하는 함수 등을 구현할 수 있습니다. 이러한 기능을 잘 사용하면 DB에서 가져온 데이터를 파이썬 코드로 반복문을 돌면서 형태를 변환하는 수고를 줄일 수 있습니다.


여기서는 복수 row를 가지는 컬럼을 단일 array로 만들거나 구분자를 주어 string 타입으로 변형하는 예시입니다.

먼저 테이블 내 컬럼은 아래와 같습니다.

test
abc
11223
가나다

array_agg

from django.contrib.postgres.aggregates import ArrayAgg


temp = Test.objects.aggregate(
    test_data_list=ArrayAgg('test_data'),
)



# {'test_data_list': ['abc', '11223', '가나다']}


공식 문서를 확인하면 ArrayAgg() 내의 옵션으로 distinct = True나 filter 조건, ordering을 줄 수 있습니다.

https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/aggregates/#arrayagg

string_agg

from django.db.models import CharField
from django.db.models.functions import Cast
from django.contrib.postgres.aggregates import StringAgg


temp = Test.objects.aggregate(
    test_data_agg=StringAgg(Cast('test_data', CharField(max_length=9)), '|')
)


# {'test_data_agg': 'abc|11223|가나다'}


array_agg와 동일하게 distinct, filter, ordering을 줄 수 있습니다.

https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/aggregates/#stringagg

unnest

unnest는 리스트로 되어 있는 데이터를 각 row로 분리하는 함수입니다.

from django.db.models import Func temp = Test.objects.annotate( test_data=Func('test_data', function='UNNEST') )


여기서 unnest를 구현하기 위해 Func라는 장고 query의 기본 표현식을 사용했습니다. 이 Func를 사용하면 장고에서 지원하지 않는 PostgreSQL 함수를 만들어 사용할 수 있습니다. 

https://docs.djangoproject.com/en/3.0/ref/models/database-functions/ 에 명시되어 있지 않는 함수를 Func로 만들어 재사용이 가능하도록 구현할 수 있습니다.