관심분야/클라우드

#9 번외편 : DynamoDB 조회 - AWS 음성지원 서비스를 활용한 신문 읽어주는 프로젝트

뱅노 2019. 11. 23. 15:14

1편부터 8편까지 해서 TTS변환 mp3를 S3에 저장을 하였다. 또한 클라이언트(웹 브라우저)와 Lambda사이에 Cognito을 활용하여 연결하였다. 이제는 DynamoDB에 있는 TTS 정보를 조회하고 mp3 다운로드, 실시간 스트리밍을 지원하면 이번 프로젝트는 종료가 된다. Lambda를 통한 DynamoDB 조회를 진행하기 전에 번외 편으로 DynamoDB의 조회 함수를 정리할 필요성을 느꼈다. 따라서 이번에는 DynamoDB 조회 함수에 대해서 정리하겠다.

 

DynamoDB에서 테이블의 데이터를 조회할 수 있는 방법은 대표적으로 4가지가 존재한다.

  • get_item
  • batch_get_item
  • query
  • scan

대표적인 4개의 조회 함수를 사용하기 전에 한가지 전제조건을 확인하자.

  • REG_DT : partitionkey
  • REG_SRNO : sortkey

조회하는 테이블 속성은 위와 같다는 전제조건이 있다.


▶ get_item

그러면 먼저 get_item 부터 알아보도록 하자. Lambda에서 직접 get_item을 호출하는 방법은 아래와 같다.

client = boto3.client('dynamodb')

# 조건값
inputVal = {
    'REG_DT' : {'S' : '20190526'}
    , 'REG_SRNO' : {'N' : '2'}
}

# get_item 호출
response = client.get_item(
    TableName = '테이블명'
    , Key = inputVal)

get_item의 경우 테이블에 데이터를 단건으로만 조회한다. 그러나 정확히 이야기하자면 단건만은 아니다.

client = boto3.client('dynamodb')

# 조건값
inputVal = {
    'REG_DT' : {'SS' : ['20190526', '20190529']}
    , 'REG_SRNO' : {'N' : '2'}
}

# get_item 호출
response = client.get_item(
    TableName = '테이블명'
    , Key = inputVal)

이렇게 REG_DT를 다건으로 sortkey REG_SRNO가 "2"인 값을 조회할 수 있다. 다건이 가능은 하지만 SQL에서의 IN 조건절 정도의 기능을 한다고 생각하면 된다.

 

▶ batch_get_item

bach_get_item은 get_item과 비교했을 때 다른점은 여러 테이블의 값들을 조회할 수 있다는 것이다. batch_get_item의 사용법은 아래와 같다.

client = boto3.client('dynamodb')

request_items = {
    'TABLE_A' : {
        'Keys' : [
                {
                    'REG_DT' : {'S' : '20190526'}
                    , 'REG_SRNO' : {'N' : '2'}
                }
            ]
    },
    'TABLE_B' : {
        'Keys' : [
                {
                    'REG_DT' : {'S' : '20190526'}
                    , 'REG_SRNO' : {'N' : '2'}
                }
            ]
    }
}

response = client.batch_get_item(RequestItems=request_items)

위 소스와 같이 TABLE_A, TABLE_B의 값을 한 번에 가지고 올 수 있다. Keys에 존재하는 값은 각 테이블의 partitionkey, sortkey이다. get_item과 동일하게 'S'를 'SS'로 변경해서 사용하면 다건으로 조회가 가능하다. 한 번에 dynamoDB 접속으로 여러 개의 테이블을 조회할 수 있다는 장점이 있다.

 

▶ query

다음은 query 함수이다. query 함수는 아래와 같이 사용이 가능하다.

client = boto3.client('dynamodb')

condition_query = 'REG_DT = :REG_DT_VAL AND REG_SRNO BETWEEN :FROM_SRNO AND :TO_SRNO'
    
condition_value = {
    ':REG_DT_VAL' : {'S' : '20190526'}
    , ':FROM_SRNO' : {'N' : '1'}
    , ':TO_SRNO' : {'N' : '10'}
}

response = client.query(
    TableName = '테이블 명'
    , KeyConditionExpression = condition_query
    , ExpressionAttributeValues = condition_value
    )

query 함수의 경우 조금은 우리가 익숙한 SQL문의 WHERE 절을 사용할 수 있다. REG_DT(partitionkey)에 원하는 일자를 Inner join을 하고 REG_SRNO(sortkey)에 1부터 10까지 조회하도록 조건절을 추가한다. 한 가지 아쉬운 점은 추가 조건절을 sortkey에만 적용할 수 있다. query 함수의 경우 위 get_item, batch_get_item과 다른 점은 sortkey 없이 partitionkey로만 조회가 가능하다.

 

▶ scan

마지막으로 scan 함수이다. scan 함수 사용은 아래와 같다.

client = boto3.client('dynamodb')

response = client.scan(TableName='테이블 명')

scan 함수는 앞에 나온 함수들과 다르게 전체 조회가 가능하다. 전체 조회가 가능하지만 query 함수처럼 조건을 추가해서 사용할 수 있다. FilterExpression 파라미터 또는 ScanFilter 파라미터 중 사용이 가능하다. 두 개를 동시에 사용할 수는 없다. FilterExpression의 경우 query 함수의 KeyConditionExpression 파라미터와 동일하게 사용이 가능하다. ScanFilter의 경우 dictionaly 형태로 조금은 직관적으로 사용이 가능하다.(개인적으로 아직 dictionaly 형태로 조회하는 게 어색하다...) scan 함수의 경우 전체 조회가 가능하다 보니 읽기 용량 제한이 존재한다. 읽기 제한에 걸리면 LastEvcaluatedKey값이 return값으로 들어온다. 그러면 LastEvcaluatedKey값을 활용해서 다시 순차적으로 scan을 하도록 프로그래밍을 해야 한다.

 

지금까지 dynamoDB의 대표적은 조회 함수 4가지를 확인해 보았다. 각 함수마다 장단점이 존재한다. 내 생각으로는 한 가지 함수만 사용하면 안 된다는 것이다. 속도, 비용, 용량과 같은 문제가 존재한다. 구축해야 하는 비즈니스의 요구에 맞은 함수를 적절하게 사용해야 한다.

 

마지막으로 내가 참고하여 작업하고 있는 boto3 API 사이트를 링크하도록 하겠다.

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html

 

DynamoDB — Boto 3 Docs 1.9.253 documentation

TableName (string) -- [REQUIRED] Name of the table for which the customer wants to check the continuous backups and point in time recovery settings.

boto3.amazonaws.com