Django 는 DB 쿼리를 수행할 때, ORM 방식을 사용합니다.
주로 sql 을 직접 작성해 왔기 때문에 익숙하지 않아 기본적인 쿼리도 장시간의 검색을 통해 사용하곤 했는데요.
최근에 model 의 aggregate 기능을 사용해 본 사례를 글로 작성해 보았습니다.
들어가며...
Django 로 개발을 진행하면서 특정 테이블의 한 컬럼에서 Max 값을 가져와야 할 일이 생겼습니다.
SQL 로 생성하면 SELECT MAX(SEQ) FROM USER 로 작성하면 되지만 ORM 방식인 django model 에서는 어떻게 구현해야 하는지 몰랐습니다.
Aggregate
보통 django query 는 CRUD(create, retrieve, update, delete) 작업에 사용합니다. 하지만 때론 sum(), max() 같은 쿼리도 수행할 때가 있는데요.
이 때 사용할 수 있는 것이 django model 에 있는 aggregate 입니다.
아래 코드는 django 공식 페이지에 나와있는 예제 코드입니다.
# Total number of books.
>>> Book.objects.count() 2452 # Total number of books with publisher=BaloneyPress >>> Book.objects.filter(publisher__name='BaloneyPress').count() 73 # Average price across all books. >>> from django.db.models import Avg >>> Book.objects.all().aggregate(Avg('price')) {'price__avg': 34.35} # Max price across all books. >>> from django.db.models import Max >>> Book.objects.all().aggregate(Max('price')) {'price__max': Decimal('81.20')} # Cost per page >>> from django.db.models import F, FloatField, Sum >>> Book.objects.all().aggregate( ... price_per_page=Sum(F('price')/F('pages'), output_field=FloatField())) {'price_per_page': 0.4470664529184653} # All the following queries involve traversing the Book<->Publisher # foreign key relationship backwards. # Each publisher, each with a count of books as a "num_books" attribute. >>> from django.db.models import Count >>> pubs = Publisher.objects.annotate(num_books=Count('book')) >>> pubs <QuerySet [<Publisher: BaloneyPress>, <Publisher: SalamiPress>, ...]> >>> pubs[0].num_books 73 # The top 5 publishers, in order by number of books. >>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5] >>> pubs[0].num_books 1323 |
Max() 를 예로 코딩해 보았습니다.
예를들어 USER 테이블에 신규 사용자 정보를 저장하기 위해 SEQ 컬럼을 MAX 값에서 +1 을 하고자 합니다.
이 때 aggregate 를 사용하여 아래와 같이 할 수 있습니다.
User.objects.all().aggregate(Max(‘seq’))[‘seq__max’] + 1
|
SELECT MAX(SEQ) + 1
FROM USER
|
한 줄로 간단하게 할 수 있습니다.
(NVL 처리는 하지 않았습니다. 실제 Production Level 에서는 NVL 처리를 하셔야 합니다.)
위에서 언급된 기능 외에도 aggregate 에는 많은 기능들이 있습니다. django 공식 문서를 참고하시면 좀 더 자세히 알 수 있습니다.
참고
- https://docs.djangoproject.com/ja/1.10/topics/db/aggregation/
- https://docs.djangoproject.com/en/1.10/ref/models/querysets/#aggregate
'Programing > django' 카테고리의 다른 글
auto_now VS auto_now_add (0) | 2016.08.19 |
---|---|
Django 기초 스터디 자료 (0) | 2016.04.04 |