오늘은 장고를 쿼리에 대해서 배워보자
장고쿼리를 배우는데 필터에 조건문을 거는데__gt??이게 뭐야? 싶어서 알아봤는데..
QuerySet API 레퍼런스 | Django 문서 | 장고(Django) (djangoproject.com)
QuerySet API reference | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
여기서 필드를 구분짓는 명령어가 따로 있다고 하는데.. 외우기는 귀찮으니 필요할 때마다 찾아서 보는걸로 해야겠다.
먼저 이것들은 filter()에서 내부적으로 조건을 넣어주기 위해서 사용을 하는 것인데.
우리가 아는 and, or, not은 각각 &, |, ~으로 표현이 됩니다.
그리고 아까 봤던 __gt는 Greater than.으로 부등호 x > 10 같이 더 많이 반대로 __lt은 더 적은 으로 됩니다.
또한 Q()는 쿼리로 써 필터 안에서 사용이 되며 products = Product.objects.filter(Q(price__gt=15000) | Q(quantity__lt=3000))
이것과 같이 각 오프젝트 필드를 넣고 조건문을 걸수 있습니다.
F()은 하나의 필드를 전부 가져올 때에 사용이 되며 아래와 같이 예시를 볼 수 있습니다.
Product.objects.update(price = F('price') + 1000)
모든 가격을 1000원 인상 하는 로직
하다보니 알게된사실 처음에 이렇게 조회를 했을 때에는 안나왔었는데.
products = Product.objects.filter(Q(price__gt=15000) | Q(quantity__lt=3000))
F로 값을 올려주니 조회가 됩니다.
처음에 선언이 되었을 때 말고도 값이 변하면 계속 조건에 맞추어 검색을 하나봅니다.
다음으로는 annotate()인데, 이것은 주석을 달아준다라고 하는데. 내가 이해하기 쉬운 말로는 특정 컬럼은 만들어준다고 보면 될 것 같습니다. 예를 들어 가격과 갯수를 곱하여 준 컬럼을 하나 만들고 싶은데, model에 추가 시키기는 그럴때?
products = Product.objects.annotate( total_price=F('price') * F('quantity') )
aggregate()는 전체적으로 종합하여 할 때 sum avg같은 기능을 쓰고 싶을 때 쓴다.
Product.objects.aggregate(Avg('price'))
# {'price__avg': 14627.76}
키값을 직접 넣어줄 수 있습니다.
Product.objects.aggregate(my_avg = Avg('price'))
# {'my_avg': 14627.76}
Product.objects.filter(Q(price__gt=15000) | Q(quantity__lt=3000)).aggregate(Avg('price'))
{'price__avg': 24124.235294117647} 필터를 쓰고도 잘 작동이 됩니다.
**IndentationError: unexpected indent 이거 뜨면 앞에 띄어쓰기 되어있다는 뜻 들여쓰기 오류!
group by하기!
먼저!
해당 값 가져오는 values()
>>> Product.objects.values('category')
<QuerySet [{'category': 'O'}, {'category': 'V'}, {'category': 'O'}, {'category': 'V'}, {'category': 'V'}, {'category': 'F'}, {'category': 'V'}, {'category': 'O'}, {'category': 'O'}, {'category': 'F'}, {'category': 'V'}, {'category': 'F'}, {'category': 'V'}, {'category': 'F'}, {'category': 'V'}, {'category': 'M'}, {'category': 'F'}, {'category': 'O'}, {'category': 'F'}, {'category': 'O'}, '...(remaining elements truncated)...']>
다음!
여기에 annotate를 하면
>>> Product.objects.values('category').annotate(category_count = Count('category'))
<QuerySet [{'category': 'F', 'category_count': 10}, {'category': 'M', 'category_count': 2}, {'category': 'O', 'category_count': 9}, {'category': 'V', 'category_count': 9}]>
이렇게 group by기능을 만들 수 있습니다.
만약에 sql문을 직접 적고싶다면? raw()를 이용하면 됩니다!.
categories_count = Product.objects.raw(
'''
SELECT "id", "category", COUNT("category") AS "category_count"
FROM "products_product"
GROUP BY "category"
'''
)
for each in categories_count:
print(each.category_count, each.category)
# 15 F
# 15 M
# 15 O
# 5 V
from django.db import connection
sql_query = '''
SELECT "category", COUNT("category") AS "category_count"
FROM "products_product"
GROUP BY "category"
'''
cursor = connection.cursor()
cursor.execute(sql_query)
result = cursor.fetchall()
print(result)
# [('F', 15), ('M', 15), ('O', 15), ('V', 5)]
정참조 역참조시 쿼리데이터 횟수를 줄이는 방법, join 계념!
- Django에서의 Eager Loading
- select_related
- one-to-many 또는 one-to-one 관계에서 사용
- SQL의 JOIN을 이용해서 관련된 객체들을 한 번에 로드하는 방식
- prefetch_related
- many-to-many 또는 역참조 관계에서 주로 사용
- (select_related를 사용하는 관계에서도 동작)
- 내부적으로 두번의 쿼리를 사용해서 동작 첫번째 쿼리는 원래 객체를 조회하며 두번째 쿼리는 연관된 객체를 가져오는 방식
- select_related
jazzband/django-silk: Silky smooth profiling for Django (github.com)
GitHub - jazzband/django-silk: Silky smooth profiling for Django
Silky smooth profiling for Django. Contribute to jazzband/django-silk development by creating an account on GitHub.
github.com
여기서 받을수 있음
redis에 대해서
db로 가기전에 redis에서 자료가 있는지 검사해서 있으면 꺼내서 사용
redis에는 여러가지 전략이 있는데.
먼저 캐시 읽기 전략
- look aside 패턴 - 요청이 들어와서 데이터를 찾으면 캐시를 찾아보고 없으면db조회 가장 기본이 되는 전략
- read through 패턴 - 캐시만 바라보고 데이터를 조회 db는 다른 서비스가 업데이트한다. 단 redis 죽으면 끝
다음은 쓰기 전략
- write back 패턴 - 데이터를 한 번에 모아서 저장 redis고장나면 날아감
- write through 패턴 - db와 redis각각쓰기 무조껀 쓰기가 2번이 일어남
- write around 패턴 - 모든 데이터 db에 바로 저장 그다음 읽기가 일어나면 redis에 옴긴다음 읽기
생성
set key value # key value 저장
조회
keys * # 모든 key 조회
get key # Key에 해당하는 value 조회
redis의 기능을 이용해서 휴대폰 인증같은 것을 만들 수 있습니다.
setex key seconds value # seconds초 뒤에 삭제되는 key value를 저장
수정
rename key newkey # key 이름 변경
expire key seconds # 해당 Key의 데이터 만료시간을 seconds초로 설정
삭제
del key1 [key2 ...] # key 삭제
'AI 코딩 교육 TIL' 카테고리의 다른 글
2024-04-26 Ai 코딩 TIL (0) | 2024.04.27 |
---|---|
2024-04-25 AI 코딩 TIL (0) | 2024.04.25 |
2024-04-23 AI 코딩 TIL (0) | 2024.04.23 |
2024-04-22 AI 코딩 TIL (0) | 2024.04.22 |
2024-04-19 AI 코딩 TIL (0) | 2024.04.19 |