티스토리 뷰

반응형

오늘은 눈과 비가 섞여서 오는 글루미한 날입니다. 커피 한잔하면서 정리할 내용은 AWS의 서비스 중에 Lambda를 통해 DynamoDB에 CRUD 하는 방법에 대해서 정리해보도록 하겠습니다. 우선 DynamoDB가 생소하신 분들은 아래 경로에서 상세한 내용을 확인하실 수 있는데 DynamoDB는 AWS의 대표격으로 사용 되는 데이터베이스이며, NoSQL Database 중 하나 입니다. 여기서 NoSQL은 무엇이냐 하면, 표준 SQL 인터페이스를 차용하지 않은 데이터베이스를 뜻하며, 정형화 된 데이터가 아니기 때문에 많은 데이터를 읽고 쓰는데에 능한 데이터베이스 입니다. 대신 SQL보다 검색속도는 느릴수 밖에 없겠지만 그 속도를 최적화 한 것이 DynamoDB라고 소개하고 있습니다.

DynamoDB는 데이터 접근을 위해 Key-Value 방식을 이용 하고, 데이터 타입으로는 JSON을 이용 합니다. 특정 Key를 통해, 그 내부에 있는 데이터에 접근하는 방식입니다. 좀더 상세한 원본 글은 아래 링크를 참조하시면 좋습니다.

https://aws.amazon.com/ko/dynamodb/

 

NoSQL 데이터베이스 | 데이터 관리 | Amazon Web Services

닫기 이 다이어그램은 Amazon DynamoDB의 핵심 기능과 기타 AWS 서비스와의 통합을 보여줍니다. 왼쪽에서 오른쪽으로 3개의 섹션이 표시되어 있습니다. 첫 번째 섹션에는 DynamoDB 서비스 아이콘 그림이

aws.amazon.com

DynamoDB 접근하기

이 글에서는 DynamoDB를 생성하고 권한을 설정하는 등에 대한 내용의 이야기는 하지 않고, Lambda를 통해 CRUD 하는 방법에 대해서 이야기 할 것인데요 우선 Lambda라는 하는 것은 함수 단위의 서비스로 파이썬, 자바스크립트, 고랭등으로 개발 할 수 있는데 저는 파이썬으로 작성하도록 할 것이고 DynamoDB에 접근하는 라이브러리는 파이썬으로 제공하는 boto3를 사용하도록 하겠습니다. 우선 Lambda를 하나 생성하시고 아래와 설명에 따라 생성해서 기본적인 테스트를 마쳤다고 가정하겠습니다.

https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-handler.html

 

Python으로 작성한 Lambda 함수 핸들러 - AWS Lambda

Python으로 작성한 Lambda 함수 핸들러 Lambda 함수의 핸들러는 이벤트를 처리하는 함수 코드의 메서드입니다. 함수가 호출되면 Lambda는 핸들러 메서드를 실행합니다. 핸들러가 존재하거나 응답을 반

docs.aws.amazon.com

boto3는 파이썬으로 제공하는 AWS SDK로 DynamoDB 외에도 다양한 기능을 제공하는데 그 중에서 오늘은 DynamoDB에 CRUD하는 가장 기본적인 방법에 대해서 설명하도록 하겠습니다.

https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html?highlight=dynamodb 

 

Amazon DynamoDB — Boto3 Docs 1.26.49 documentation

Amazon DynamoDB By following this guide, you will learn how to use the DynamoDB.ServiceResource and DynamoDB.Table resources in order to create tables, write items to tables, modify existing items, retrieve items, and query/filter the items in the table. C

boto3.amazonaws.com

Create

db = boto3.resource('dynamodb', region_name='ap-northeast-2')
    table = db.Table(os.environ['table'])
    table.put_item(
        body={
            'email' : event['email'],
            'userName' : event['userName'],
            'problems' : [event['problems']],
            'lifeSchedule' : event['lifeSchedule'],
            'age' : event['age'],
            'location' : event['location'],
            'sex' : event['sex'],
        }
    )

 

데이터베이스를 하나 생성했을때 그 안에 있는 테이블 이름은 변경될 수 있으니 Lambda에서 지원하는 os.environ 기능으로 매핑시키고 그 테이블안에 email, userName, Problems, LifeSchedule, age, location, sex 값을 가진 데이터를 생성하고자 구성한 코드입니다. create 할때 put_item이라는 인터페이스를 사용하고 있고 region_name은 ap-northeast-2를 썻는데 자신이 생성한 dynamoDB가 어디 region에 있는지 적어 주었습니다.

Read

import json, os
import boto3
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    db = boto3.resource('dynamodb', region_name='ap-northeast-2')
    table = db.Table(os.environ['table'])
    
    try:
        res = table.get_item(Key={
            'email' : 'test@gmail.com',
        })
        return {
            'statusCode' : 200,
            'body' : json.dumps(res),
        }
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        return response['Item']

테이블의 값을 read할때는 특정 데이터를 찾아서 넘겨주고자 email일을 key로 넣어주었고 get_item 이라는 인터페이스를 사용했습니다. key의 경우 다양한 식응ㄹ 넣을 수 있기에 관련해서는 문서를 좀더 찹조해주시고, 값이 없거나 하는 경우를 대비해서 try except 구문을 사용하였습니다. 정상적으로 리턴되면 json 구조로 담아서 리턴되도록 작성하였습니다.

Update

# update to DB
    try:
        res = usersTable.update_item(Key={
            'email' : email,
            },
        UpdateExpression=updateExpression,
        ExpressionAttributeNames=updateNames,
        ExpressionAttributeValues=updateVals)

    except:
        raise Exception(json.dumps({
            'statusCode' : 500,
            'message': "Internal Server Error. Fail to update users table."
        }))

Update의 경우에는 기존에 존재하는 데이터에 업데이트하는 개념이므로 put_item이 아닌 update_item 이라는 인터페이스를 사용하고 있습니다. update 에서 가장 중요한 것은 UpdateExpression 식을 만ㄷ는 것인데요, 관련해서는 별도 글로 좀더 자세히 다루도록 하겠습니다. 이유는 update 라는 것의 고려해야할 케이스가 다양한데요. 이를테면 업데이트 할 데이터가 없는 상황에서는 생성되도록 하는 것인가? 업데이하려는 데이터가 있으나, 맵타입인데 그중에 한가지 값만 들어왔을경우 어떻게 해야하는가? 등의 케이스가 있기에 정책을 정한 뒤 업데이트가 필요합니다.

Delete

# whether user exists in DB
    try:
        queryResponse = table.query(
            KeyConditionExpression=keyCondition
        )
        
        if queryResponse["Count"] == 0:
            logger.info("No item to delete: " + str(table))
            return {
                    "statusCode": 200
                }
    
        # has data    
        try:
            response = table.delete_item(
                Key={
                    'email': emailFromToken,
                },
            )
            return response
            
        except:
            raise Exception(json.dumps({
                'statusCode' : 500,
                'message' : "Internal Server Error. Fail to delete item in table."
            }))
            
    except:
        raise Exception(json.dumps({
            'statusCode' : 500,
            'message' : "Internal Server Error. Fail to access table."
        }))

delete하려면 delete 할 데이터가 존재해야 하겠죠? 먼저 query를 통해 데이터가 있는지 확인 하고, 데이터가 있다면 삭제를 하기위해 delete_item 인터페이스를 이용해서 요청하게 되면 삭제됩니다.

지금까지 간단하게 boto3를 이용해서 파이썬으로 AWS의 NoSQL 데이터베이스인 DynamoDB의 CRUD 하는 법에 대해서 알아 봤습니다. 지금은 비단, 간단한 케이스에 대해서 설명을 하였으나, query할때, update할때 식에 따라 다양하게 사용할 수 있으니 관련해서는 별도의 글로 설명하도록 하겠습니다.

반응형
댓글