-
[Django] Boto3 사용하여 AWS DynamoDB query하기Django 개발 2023. 3. 13. 20:11
python 3.8.13 / boto3 1.17 / django 3.1 버전에서 작성된 글입니다.
from boto3 import Session boto3_session = Session(aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=AWS_REGION_NAME)
boto3를 사용하여 DynamoDB에 query하는 방법은 client를 사용하는 방법과 resouce를 사용하는 방법 두 가지가 있다. 먼저 두 가지의 차이점은 client가 좀 더 row level, resource가 좀 더 high level이라고 하는데 recource가 client를 wrapping한 고수준 인터페이스를 제공한다고 한다. 그래서 resource가 더 개발자 친화적이고 사용하기 편하다. 하지만 모든 client의 모든 기능을 resource에서 제공하는 것은 아니기 때문에 client를 직접 사용해야 하는 경우도 있다고 한다.
query 기능의 경우 client와 resource 모두 기능을 제공하고 있기 때문에 쿼리문과 응답을 비교하면 좋을 것 같아서 가져와보았다.
예제 코드는 오늘로부터 90일 이내의 특정 유저 알림함에 있는 데이터를 모두 가져오는 코드이다. 참고로 여기서 사용하는 AWS 계정에 DynamoDB Query에 대한 role을 허용해주어야 한다.
Client를 사용해서 Query하기
class Notification(): """ 알림함 DynamoDB """ def __init__(self): self._client = boto3_session.client('dynamodb') self._table_name = 'notification-test' self._items_buffer = [] self._fail_items_buffer = [] self._flush_amount = 25 def query(self, user_id): today = get_utc_date_today() before_90days = today - timedelta(days=90) response = self._client.query( TableName=self._table_name, KeyConditionExpression='userId = :userId', FilterExpression='created BETWEEN :before_90days AND :today', ExpressionAttributeValues={ ':userId': {'N': str(user_id)}, ':before_90days': {'S': str(before_90days)}, ':today': {'S': str(today)} } ) return response
notification-test는 userId가 hash key이고 range key는 별도의 unique한 키로 지정되어 있는 테이블이다. 이때 위와 같이 KeyConditionExpression으로 일치하는 hash key를 지정해주고, local seconday index로 지정해준 created 값을 filter로 사용한다.
그러면 Itmes가 "key": {"type": "value"} 형식으로 보여지게 된다. 그런데 해당 응답을 그대로 프론트에 내려주기에는 어려워보인다. "key": "vlaue" 형태로 바꾸려면 어떻게해야 할까?
Resource를 사용해서 Query하기
class Notification(): """ 알림함 DynamoDB """ def __init__(self): self._resource = boto3_session.resource('dynamodb') self._table_name = 'notification-test' self._items_buffer = [] self._fail_items_buffer = [] self._flush_amount = 25 def query(self, user_id): today = get_utc_date_today() before_90days = today - timedelta(days=90) response = self._resource.Table(self._table_name).query( KeyConditionExpression=Key('userId').eq(user_id), FilterExpression=Key('created').between(str(before_90days), str(today)) )['Items'] return response
resource를 사용하면 쉽게 해결할 수 있다. 아까도 말했듯 resource는 client를 wrapping하여 제공되기 때문에 우리가 원하는 "key": "value" 형태의 format으로 응답을 내려준다.
참고한 문서
반응형'Django 개발' 카테고리의 다른 글
[Django] N:M 관계에서 order_by 사용시 duplicate 오류 (0) 2022.11.29 [Pycharm]디버깅 No such file or directory 오류 해결 (0) 2022.05.20 [Docker] No such file or directory: 'docker' 오류 해결 (0) 2022.04.25 [Django] DRF jwt 인증방식을 이용한 로그인, 회원가입 구현하기 (0) 2022.03.28 [Django] postman 로그인 API CSRF token missing 오류 해결 (1) 2022.02.21