본문 바로가기

Django

(17)
트랜잭션 race condition 처리 1. 문제 특정 게시물의 조회수를 센다거나, 은행 계좌의 잔고를 관리하는 어플리케이션을 로직을 개발한다고 가정해보자. 이런 경우에 원래 모델의 값을 읽어서, +1 을 한다거나 특정 값을 더해서 새로운 값을 업데이트한다. Django에서 race condition을 고려하지 않고 단순하게 코드를 짜면 다음과 같이 짤 수 있다. post = Post.objects.get(id=1) post.view_count = post.view_count + 1 post.save() ---------- account = BankAccount.objects.get(id=1) account.balance = account.balance + remittance_ammount account.save() 위 코드는 race con..
DRF 메가 쇼핑몰 쿠폰 발급 동시성 문제 해결 커머스 도메인을 다루는 서비스를 보면 쿠폰을 제공하는 기능이 꼭 하나씩은 존재한다. 선착순으로 진행하는 경우도 있고 그렇지 않은 경우도 있는데, 대다수의 쿠폰은 재고를 가지기 마련이다. 단순하게 생각한다면 DB에 쿠폰의 재고를 저장해두고 유저가 쿠폰을 획득할 때 마다 재고를 하나씩 차감하면 된다고 생각할 수 있는데 여기에는 큰 문제점이 하나 존재한다. 예를 들어 100개의 쿠폰을 발급할 수 있다고 가정해보자. 99개의 쿠폰이 소진되었고 재고가 1개 남은 상태이다. 이때 A라는 유저가 재고를 조회하고 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 그리고 동시에 B유저가 재고 조회를 진행하고 마찬가지로 데이터베이스에서는 1개의 재고가 남았다고 알려준다. 다음으로 A가 쿠폰을 획득함과 동시에 재고를 1개..
[Django] ManyToMany Field를 이용한 태그 구현 메가 쇼핑몰 서비스에서 마켓 생성시 해시태그도 같이 생성되게끔 구현하려고 한다. 해시 태그는 ManyToMany 필드를 사용할 것이다. 아래의 사진처럼 마켓에 해시태그를 추가해서 해당 마켓이 추구하는 스타일 또는 의미를 나타내게 하는 것이다. 1. 모델 Tag 모델 # tag/models.py class Tag(models.Model): name = models.CharField('태그', max_length=30, unique=True) class Meta: db_table = 'tag' def __str__(self): return self.name Market 모델 market/models.py class Market(models.Model): name = models.CharField('마켓 이름..
[Django] 데이터 쿼리 스트링을 이용한 검색 및 필터링 성능 개선 ( + ElasticSearch ) 예정
[Django] 메가 쇼핑몰 인기 상품 랭킹 조회 ( + Redis or ElasticSearch ) 에이블리와 브랜디, 무신사와 같은 메가 쇼핑몰 특성상 수 십개 또는 수 백개의 마켓이 있고 굉장히 많은 상품의 데이터를 가지고 있을 때, 마켓 상관 없이 조회수와 평점이 높은 상품의 리스트를 보고싶은 경우는 어떻게 할까 라는 고민이 생겼다. 나름 개발한 경험이 좀 있어서 그런지는 모르겠지만, 쇼핑몰 특성상 상품 데이터는 RDBMS로 관리를 할 것이고, 모든 상품을 조회하면서 평점 또는 조회수를 가지고 상품 랭킹을 나타내는 것에 대해서 RDBMS를 계속 접근한다는 것은 성능적인 큰 이슈를 불러올 것만 같은 느낌이 강하게 들었다. 이 고민을 가지고 한번 테스트를 해볼 생각이다. 1. RDBMS 2. Redis 3. ElasticSearch
[Django] ORM 성능 개선하기 ( + debug toolbar ) Django를 사용하면서 ORM도 자주 사용해보고 queryset을 만들어서 API를 여러번 개발공부를 해왔지만, 해당 API를 호출할 때마다 요청시간이 길어진다는 것을 느끼게 되었고, 디버그 툴바를 이용해서 어떤 쿼리가 반복되는지를 확인해 보았다. 메가 쇼핑몰을 개발하던 도중 여러 모델과의 관계가 복잡해지지만 반대로 쿼리셋은 복잡해진 모델 관계와는 다르게 큰 변화가 없었다. 이렇게 개발해도 되나? 라는 의문이 들었고 성능에 대해서도 관심을 점차 갖게 되었다. 1. 기존의 문제점 메가 쇼핑몰 특성상 마켓관리자는 자신의 마켓에서 판매하는 상품들을 CRUD할 수 있어야 한다. 즉, Product 모델은 다양한 모델과의 관계를 형성하고 있다. 기존의 마켓 별 상품 리스트 API를 호출해보면, 12 querie..
[DRF] queryset과 get_queryset()의 차이점 본인은 DRF 라이브러리에서 viewsets과 mixin 기능을 사용해서 API 개발을 자주한다. 클래스형 view를 개발하다보면, def get_queryset(self):​ 이라는 함수를 클래스 내에 내장하는 경우가 있는데 class API(mixin.어쩌고, viewsets.어쩌고): queryset = 어쩌고 . . .​ 위의 코드 처럼 queryset을 기본적으로 사용할 것이다. 그러면 get_queryset 함수는 왜 사용해야할까? queryset VS get_queryset() 분명 queryset과 get_queryset()은 같은 동작을 한다. 하지만, 필터의 값이 동적일 경우 잘못된 쿼리가 나올 수 있다. # 필터의 값이 동적일 경우 잘못된 쿼리가 나올 수 있음 # (X) class L..
[Django] DecimalField DecimalField 10 진수 표현으로, python에서 Decimal 인스턴스로 나타낸다. django.db.models.fields.DecimalField에 해당한다. FloatField는 소수점의 근사값을 제공하지만 DeciamalField는 소수점 자리를 설정해서 원하는 자릿수만큼 출력이 가능하다. 1. 구성 인자 DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits : 숫자에 허용되는 최대 자릿수를 말하며, None이거나 decimal_places보다 크거나 같은 정수여야 함 decimal_places : 숫자와 함께 저장할 소수 자릿수를 말함 coerce..