๐Ÿšฆ ์žฅ๊ณ  Annotate & Aggregate

may_soouuยท2020๋…„ 9์›” 28์ผ
4

Django-ORM

๋ชฉ๋ก ๋ณด๊ธฐ
3/5

1. annotate

annotate๋Š” ์žฅ๊ณ ์˜ ์ฟผ๋ฆฌํ‘œํ˜„์‹ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

1-1. ํ•„๋“œ ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐ

๋‘๊ฐ€์ง€์˜ ๋ชจ๋ธ์ด ์žˆ๊ณ , foreign key๋กœ ์—ฐ๊ฒฐ๋๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž

class Product(models.Model):
    name  = models.CharField('์ด๋ฆ„', max_length=150)
    price = models.IntegerField('๊ฐ€๊ฒฉ')
========================================================
class OrderLog(models.Model):
    product = models.ForeignKey('Product')
    created = models.DateTimeField() #ํŒ๋งค์ผ

๐Ÿ” ์ฟผ๋ฆฌ์…‹์—์„œ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ

order_log = OrderLog.objects.values('created', 
'product__name','product__price')
 # ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ์žˆ๋Š” ์นผ๋Ÿผ์„ ๋ถˆ๋Ÿฌ์˜ค๋ ค๋ฉด ์œ„์— ์ž…๋ ฅํ•œ ๊ฒƒ์ฒ˜๋Ÿผ 
 # 'ํด๋ž˜์Šค๋ช…์†Œ๋ฌธ์ž__๋ถˆ๋Ÿฌ์˜ค๋ ค๋Š” ์นผ๋Ÿผ๋ช…' ์„ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

๊ทธ๋Ÿผ ์ฟผ๋ฆฌ์…‹ ๊ฒฐ๊ณผ๊ฐ€

{'product__price': 9900, 'created': datetime.datetime(2016, 4, 1, 0, 0), 'product__name': 'ABC Activity'}
{'product__price': 8200, 'created': datetime.datetime(2016, 4, 1, 0, 0), 'product__name': '๋™๋ฌผ๋™์š”'}

์ด๋Ÿฐ์‹์œผ๋กœ ์–ธ๋”๋ฐ”๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚˜์˜จ๋‹ค.
annotate๋ฅผ ์จ์„œ ๋ฐ”๊ฟ”๋ณด์ž

order_log = OrderLog.objects.annotate(
	                     name =F('product__name'),
                             price=F('product__price')
                             .values('created','name','price')

๊ทธ๋Ÿผ ๊ฒฐ๊ณผ๊ฐ€ ์ด๋ ‡๊ฒŒ ๋‚˜์˜จ๋‹ค!!!

{'price': 9900, 'created': datetime.datetime(2016, 4, 1, 0, 0), 'name': 'ABC Activity'}
{'price': 8200, 'created': datetime.datetime(2016, 4, 1, 0, 0), 'name': '๋™๋ฌผ๋™์š”'}

1-2. ์–ด๋– ํ•œ ๊ธฐ์ค€์œผ๋กœ ๊ฐ’์„ ๋ฌถ์„ ๋•Œ

ex. ๋‚ ์งœ๋ณ„(created)๋กœ ๊ฐ’์„ ๋ฌถ๊ณ  ์‹ถ์„ ๋•Œ

daily_list = order_log.values(
'created'
).annotate(daily_total=Sum('product__price'))

1-3. ๋ชจ๋ธ์˜ ์นผ๋Ÿผ ๊ฐฏ์ˆ˜ ์„ธ๊ธฐ

์žฅ๊ณ ์˜ models.py์—์„œ ํด๋ž˜์Šค์˜ ์นผ๋Ÿผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋ช‡๊ฐœ ์žˆ๋Š”์ง€ ํ™•์ธ ํ•  ๋•Œ
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚˜๋Š” models.py ์—

class Category(models.Model):
	name          = models.CharField(max_length = 45)
	main_category = models.ForeignKey(MainCategory, on_delete=models.CASCADE)

์ฒ˜๋Ÿผ ๋กœ์ง์„ ์งฐ๊ณ , category๋ผ๋Š” ํด๋ž˜์Šค์— name์นผ๋Ÿผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋ช‡๊ฐœ ์ธ์ง€ ํ™•์ธํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด

n = Category.objects.annotate(Count('name'))
> ๊ฒฐ๊ณผ : <QuerySet [<Category: Category object (1)>, <Category: Category object (2)>, <Category: Category object (3)>, <Category: Category object (4)>, <Category: Category object (5)>, <Category: Category object (6)>, <Category: Category object (7)>]>

#row์˜ ๋ฐ์ดํ„ฐ๋ช… ์ถœ๋ ฅ
n[0].name
> NEW ARRIVAL

์ด๋ ‡๊ฒŒ ๋œฌ๋‹ค. ์‹ค์ œ ๋‚ด ๋ฐ์ดํ„ฐ์— 7๊ฐœ์˜ row๊ฐ€ ์กด์žฌํ•œ๋‹ค.

2. aggregate

Django ์—์„œ๋Š” ํ•„๋“œ ์ „์ฒด์˜ ํ•ฉ, ํ‰๊ท , ๊ฐœ์ˆ˜ ๋“ฑ์„ ๊ณ„์‚ฐํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค

from django.db.models import F, Sum, Count, Case, When

order_log.aggregate(totle_price=Sum('price'))
{'total_price': 262200}

์ถœ์ฒ˜ : ์ฐธ๊ณ ์‚ฌ์ดํŠธ

profile
back-end ๊ฐœ๋ฐœ์ž

0๊ฐœ์˜ ๋Œ“๊ธ€