ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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으로 응답을 내려준다.

     

     

    참고한 문서

     

    Ten Examples of Getting Data from DynamoDB with Python and Boto3

    Ten practical examples of using Python and Boto3 to get data out of a DynamoDB table.

    www.fernandomc.com

     

    반응형

    댓글

Written by 나도개발자.