본문 바로가기
IT/클라우드

[AWS] #3 SDK(python)로 DynamoDB 서비스 관리

by 옥탑방개발자 2020. 6. 18.
728x90

CRUD

 

1. 새로운 항목 추가

  • MoviesItemOps01.py로 저장 및 실행
  • dynamodb = boto3.resource('dynamodb', endpoint_url="주소")로 DB에 엑세스할 수 있다.
  • dynamodb.Table로 테이블 불러오기
  • table.put_item으로 새로운 항목 추가할 수 있음
from pprint import pprint
import boto3


def put_movie(title, year, plot, rating, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')
    response = table.put_item(
       Item={
            'year': year,
            'title': title,
            'info': {
                'plot': plot,
                'rating': rating
            }
        }
    )
    return response


if __name__ == '__main__':
    movie_resp = put_movie("The Big New Movie", 2015,
                           "Nothing happens at all.", 0)
    print("Put movie succeeded:")
    pprint(movie_resp, sort_dicts=False)

2. 읽기

  • MoviesItemOps02.py로 저장 및 실행
  • table.get_item(key={'키':값, '키':값})으로 데이터를 읽을 수 있다.
from pprint import pprint
import boto3
from botocore.exceptions import ClientError


def get_movie(title, year, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

    try:
        response = table.get_item(Key={'year': year, 'title': title})
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        return response['Item']


if __name__ == '__main__':
    movie = get_movie("The Big New Movie", 2015,)
    if movie:
        print("Get movie succeeded:")
        pprint(movie, sort_dicts=False)

 

3. 업데이트

  • MoviesItemOps03.py로 저장 및 실행
  • table.update_item(key={'키':값, '키':값...})으로 업데이트 할 수 있음
  • ReturnValues 파라미터는 DynamoDB에게 업데이트된 속성(UPDATED_NEW)만 반환하도록 함
  • rating, plot의 값을 변경하고, actors컬럼을 추가한다
  • Boto SDK는 Decimal 클래스를 사용하여 Amazon DynamoDB 숫자 값을 저장합니다.
  • 지정된 항목에 대해 수행하고자 하는 모든 업데이트를 설명하기 위해 UpdateExpression을 사용함
from decimal import Decimal
from pprint import pprint
import boto3


def update_movie(title, year, rating, plot, actors, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

    response = table.update_item(
        Key={
            'year': year,
            'title': title
        },
        UpdateExpression="set info.rating=:r, info.plot=:p, info.actors=:a",
        ExpressionAttributeValues={
            ':r': Decimal(rating),
            ':p': plot,
            ':a': actors
        },
        ReturnValues="UPDATED_NEW"
    )
    return response


if __name__ == '__main__':
    update_response = update_movie(
        "The Big New Movie", 2015, 5.5, "Everything happens all at once.",
        ["Larry", "Moe", "Curly"])
    print("Update movie succeeded:")
    pprint(update_response, sort_dicts=False)

 

4. 지속 업데이트

  • MoviesItemOps04.py로 저장 및 실행
  • 프로그램이 실행 될 때마다 rating+1된다
from decimal import Decimal
from pprint import pprint
import boto3


def increase_rating(title, year, rating_increase, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

    response = table.update_item(
        Key={
            'year': year,
            'title': title
        },
        UpdateExpression="set info.rating = info.rating + :val",
        ExpressionAttributeValues={
            ':val': Decimal(rating_increase)
        },
        ReturnValues="UPDATED_NEW"
    )
    return response


if __name__ == '__main__':
    update_response = increase_rating("The Big New Movie", 2015, 1)
    print("Update movie succeeded:")
    pprint(update_response, sort_dicts=False)

 

5. 업데이트(조건부)

  • MoviesItemOps05.py로 저장 및 실행
  • ConditionExpression = "size(info.actors) > = :num", 현재 actors 사이즈 값보다 입력값이 이상일 때 True

 

from pprint import pprint
import boto3
from botocore.exceptions import ClientError


def remove_actors(title, year, actor_count, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

    try:
        response = table.update_item(
            Key={
                'year': year,
                'title': title
            },
            UpdateExpression="remove info.actors[0]",
            ConditionExpression="size(info.actors) >= :num",
            ExpressionAttributeValues={':num': actor_count},
            ReturnValues="UPDATED_NEW"
        )
    except ClientError as e:
        if e.response['Error']['Code'] == "ConditionalCheckFailedException":
            print(e.response['Error']['Message'])
        else:
            raise
    else:
        return response


if __name__ == '__main__':
    print("Attempting conditional update (expecting failure)...")
    update_response = remove_actors("The Big New Movie", 2015, 3)
    if update_response:
        print("Update movie succeeded:")
        pprint(update_response, sort_dicts=False)

 

 

6. 삭제

  • MoviesItemOps06.py로 저장 및 실행
  • delete_item 메서드를 사용해 기본 키를 지정함으로써 항목 1개를 삭제할 수 있습니다. 조건을 충족하지 않는 경우 ConditionExpression을 제공하여 항목 삭제를 방지하는 옵션을 선택할 수 있습니다.
  • 현재 rating값이 6.5이기때문에 입력값 5보다 작아 True가 아니므로 삭제는 돼지 않는다. 삭제하고싶으면 조건부를 삭제하고 실행하면됨.
from decimal import Decimal
from pprint import pprint
import boto3
from botocore.exceptions import ClientError


def delete_underrated_movie(title, year, rating, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

    try:
        response = table.delete_item(
            Key={
                'year': year,
                'title': title
            },
            ConditionExpression="info.rating <= :val",
            ExpressionAttributeValues={
                ":val": Decimal(rating)
            }
        )
    except ClientError as e:
        if e.response['Error']['Code'] == "ConditionalCheckFailedException":
            print(e.response['Error']['Message'])
        else:
            raise
    else:
        return response


if __name__ == '__main__':
    print("Attempting a conditional delete...")
    delete_response = delete_underrated_movie("The Big New Movie", 2015, 5)
    if delete_response:
        print("Delete movie succeeded:")
        pprint(delete_response, sort_dicts=False)

*서비스 및 인스턴스는 사용하지 않으면 중지 및 삭제 한다. (과금발생방지)

728x90