본문 바로가기

개발/AWS

[dynamoDB] decimal을 모두 int로 변환하는 법

dynamoDB에서 query를 하거나 scan을 해서 값들을 가져오면, 숫자가 Decimal 형태로 나오게 됩니다. 

이 때 모든 Decimal들을 한 번에 int형으로 바꾸는 방법에 대해 소개하겠습니다.

{'Items': 
	[{'email': 'example@gmail.com', 'nickname': 'coffee', 'age' : Decimal(20)},
     {'email': 'example2@gmail.com', 'nickname': 'muffin', 'age' : Decimal(10)}], 
    'Count': 2,
    'ScannedCount': 2,
    'ResponseMetadata': {'RequestId': 'ABCDEFG', 'HTTPStatusCode': 200, 
    					'HTTPHeaders': {'server': 'Server', 
                        				'date': 'Thu, 07 Oct 2021 06:04:47 GMT', 
                        				'content-type': 'application/x-amz-json-1.0', 
                                        'content-length': '97', 
                                        'connection': 'keep-alive', 
                                        'x-amzn-requestid': 'ABCDEFG',
                                        'x-amz-crc32': '2222222222'}, 
                                        'RetryAttempts': 0}}

 

1. DecimalEncoder 클래스 작성

람다 함수에 import decimal을 하고, 다음과 같은 클래스를 하나 만들어줍니다.

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            return int(obj)
        return super(DecimalEncoder, self).default(obj)

코드 출처 : https://www.reddit.com/r/aws/comments/bwvio8/dynamodb_has_been_storing_integers_as/

2. json.dumps를 하고 json.loads로 다시 풀어주기

그리고 query해온 결과를 json으로 만들 때, 위의 클래스를 사용하여 만들어줍니다. 그렇게 하면 json으로 만들어지는 값이 int가 되어 만들어지게 됩니다.

ret = json.dumps(res['Items'], cls=DecimalEncoder)

그런데 return을 할 때, json 덤프가 되어 있는 것을 그대로 리턴하지 않고 오직 json형태로만 되어 있는 것을 리턴하기 위해서는 json으로 묶어주었던 것을 다시 풀어주어야 합니다.

ret = json.loads(ret)

json.loads를 사용하여 다시 풀어준 다음 return해주면 됩니다.