ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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로 만들어 재사용이 가능하도록 구현할 수 있습니다.

    댓글