-
[Django] array_agg, string_agg, unnest ORM으로 구현하기언어/파이썬 & 장고 2020. 3. 7. 18:38
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로 만들어 재사용이 가능하도록 구현할 수 있습니다.