LocalStackで AWS CLI（awscli-local）を使って、DynamoDBを操作してみる。

# はじめに

前回、 docker-compose.yml について、Amazon DynamoDB を動作させるための設定をして、 LocalStack を起動した後、 AWS CLI を利用した操作を試せるようにしました。

https://qiita.com/ryamate/items/fb9bd0bed550cdbe118b

今回は、 LocalStack で AWS CLI（awscli-local）を使って、 Amazon DynamoDB を操作してみます。

## 環境

- MacBook Pro (Intel)、macOS Big Sur 11.6
- Docker Desktop 4.7.0
    - Docker Engine 20.10.14

## 目次

Amazon DynamoDB の操作を以下の順番に試していきます。
1. [テーブルのリスト表示 list-tables](#1-テーブルのリスト表示-list-tables)
1. [テーブルの作成 create-table](#2-テーブルの作成-create-table)
1. [テーブル詳細の表示 describe-table](#3-テーブル詳細の表示-describe-table)
1. [アイテムの書き込み put-item](#4-アイテムの書き込み-put-item)
1. [アイテム一覧の取得 scan](#5-アイテム一覧の取得-scan)
1. [アイテムの取得 get-item](#6-アイテムの取得-get-item)
1. [アイテムの更新 update-item](#7-アイテムの更新-update-item)
1. [アイテムの削除 delete-item](#8-アイテムの削除-delete-item)
1. [テーブルの削除 delete-table](#9-テーブルの削除-delete-table)

テーブルを作成して、そこにアイテムを書き込みしたりして、さいごにテーブルを削除する、という 1〜9 の一連を連続して実行したときのログを添えています。

## Amazon DynamoDB とは

以下、公式ドキュメントの概要です。

> Amazon DynamoDB は、フルマネージドの NoSQL データベースサービスであり、高速で予測可能なパフォーマンスとシームレスな拡張性が特長です。
> 

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html

本記事のコマンドは、公式ドキュメントのページ内のコマンドの例を参考に試しました。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/WorkingWithTables.Basics.html    


## Docker コンテナの起動

Docker コンテナ内でコマンドを実行するため、下記コマンドを実行します。

```bash
docker compose exec localstack /bin/bash
```
    
```bash:実行時ログ
# r_yamate @ mbp in ~/Documents/code/localstack_dynamodb [20:33:52]
$ docker compose exec localstack /bin/bash
root@38868ff8bde4:/opt/code/localstack#
```
    
# 1. テーブルのリスト表示 list-tables

テーブルをリスト表示する `list-tables` を実行します。

```bash
awslocal dynamodb list-tables
```
    
```bash:実行時ログ
root@38868ff8bde4:/opt/code/localstack# awslocal dynamodb list-tables
{
    "TableNames": []
}
```
    
- 確認：list-tables のリファレンス
    
https://docs.aws.amazon.com/cli/latest/reference/dynamodb/list-tables.html
    
# 2. テーブルの作成 create-table

テーブルを作成する `create-table` を実行します。

```bash
awslocal dynamodb create-table \
    --table-name User \
    --attribute-definitions \
        AttributeName=Name,AttributeType=S \
        AttributeName=Birthday,AttributeType=S \
    --key-schema \
				AttributeName=Name,KeyType=HASH \
				AttributeName=Birthday,KeyType=RANGE \
    --billing-mode=PAY_PER_REQUEST

```
    
```bash:実行時ログ
{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "Name",
                "AttributeType": "S"
            },
            {
                "AttributeName": "Birthday",
                "AttributeType": "S"
            }
        ],
        "TableName": "User",
        "KeySchema": [
            {
                "AttributeName": "Name",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "Birthday",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1670923056.433,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:ap-northeast-1:000000000000:table/User",
        "TableId": "c8ab94aa-17d2-47cc-8738-cedd2bd96e76",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": 1670923056.433
        }
    }
}
```
    
- 確認：create-table のリファレンス
    
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/create-table.html

# 3. テーブル詳細の表示 describe-table

テーブルに関する情報を表示する `describe-table` を実行します。

```bash
awslocal dynamodb describe-table --table-name User
```
    
```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb describe-table --table-name User
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "Name",
                "AttributeType": "S"
            },
            {
                "AttributeName": "Birthday",
                "AttributeType": "S"
            }
        ],
        "TableName": "User",
        "KeySchema": [
            {
                "AttributeName": "Name",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "Birthday",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1670985611.092,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/User",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": 1670985611.092
        }
    }
}
```

# 4. アイテムの書き込み put-item

テーブルに新しいアイテムを作成するか、古いアイテムを新しいアイテムに置き換える `put-item` を実行します。

```bash
awslocal dynamodb put-item \
    --table-name User \
    --item \
        '{"Name": {"S": "Yamate"}, "Birthday": {"S": "1986-06-28"}, "Age": {"S": "36"}}'
```
    
```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb put-item \
>     --table-name User \
>     --item \
>         '{"Name": {"S": "Yamate"}, "Birthday": {"S": "1986-06-28"}, "Age": {"S": "36"}}'
root@e4f2c4a95830:/opt/code/localstack#
```    

もう 2 つアイテムを作成しておきます。

```bash
awslocal dynamodb put-item \
    --table-name User \
    --item \
        '{"Name": {"S": "Yamaimo"}, "Birthday": {"S": "1600-01-01"}, "Age": {"S": "422"}}'

awslocal dynamodb put-item \
    --table-name User \
    --item \
        '{"Name": {"S": "Satsumaimo"}, "Birthday": {"S": "1600-02-02"}, "Age": {"S": "422"}}'
```
    
```bash:実行時ログ①
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb put-item \
>     --table-name User \
>     --item \
>         '{"Name": {"S": "Yamaimo"}, "Birthday": {"S": "1600-01-01"}, "Age": {"S": "422"}}'
```
    
```bash:実行時ログ②
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb put-item \
>     --table-name User \
>     --item \
>         '{"Name": {"S": "Satsumaimo"}, "Birthday": {"S": "1600-02-02"}, "Age": {"S": "422"}}'
```

# 5. アイテム一覧の取得 scan

テーブルの全アイテムとアイテム属性を返す `scan` を実行します。

```bash
awslocal dynamodb scan --table-name User
```

```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb scan --table-name User
{
    "Items": [
        {
            "Birthday": {
                "S": "1600-02-02"
            },
            "Age": {
                "S": "422"
            },
            "Name": {
                "S": "Satsumaimo"
            }
        },
        {
            "Birthday": {
                "S": "1600-01-01"
            },
            "Age": {
                "S": "422"
            },
            "Name": {
                "S": "Yamaimo"
            }
        },
        {
            "Birthday": {
                "S": "1986-06-28"
            },
            "Age": {
                "S": "36"
            },
            "Name": {
                "S": "Yamate"
            }
        }
    ],
    "Count": 3,
    "ScannedCount": 3,
    "ConsumedCapacity": null
}
```

# 6. アイテムの取得 get-item

指定された主キーを持つアイテムの属性セットを返す `get-item` を実行します。

```bash
awslocal dynamodb get-item \
    --table-name User \
    --key '{ "Name": { "S": "Yamate" },  "Birthday": { "S": "1986-06-28" }  }' 
```
    
```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb get-item \
>     --table-name User \
>     --key '{ "Name": { "S": "Yamate" },  "Birthday": { "S": "1986-06-28" }  }'
{
    "Item": {
        "Birthday": {
            "S": "1986-06-28"
        },
        "Age": {
            "S": "36"
        },
        "Name": {
            "S": "Yamate"
        }
    }
}
```
    

# 7. アイテムの更新 update-item

既存の項目の属性を編集し、まだ存在しない場合は新しい項目をテーブルに追加する `update-item` を実行します。

```bash
awslocal dynamodb update-item \
    --table-name User \
    --key '{ "Name": {"S": "Yamaimo"}, "Birthday": {"S": "1600-01-01"}}' \
    --update-expression "SET Age = :age" \
    --expression-attribute-values '{":age":{"S":"423"}}' \
    --return-values ALL_NEW

```
    
```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb update-item \
>     --table-name User \
>     --key '{ "Name": {"S": "Yamaimo"}, "Birthday": {"S": "1600-01-01"}}' \
>     --update-expression "SET Age = :age" \
>     --expression-attribute-values '{":age":{"S":"423"}}' \
>     --return-values ALL_NEW
{
    "Attributes": {
        "Birthday": {
            "S": "1600-01-01"
        },
        "Age": {
            "S": "423"
        },
        "Name": {
            "S": "Yamaimo"
        }
    }
}
```

# 8. アイテムの削除 delete-item

既存の項目の属性を編集し、まだ存在しない場合は新しい項目をテーブルに追加する `delete-item` を実行します。

```bash
awslocal dynamodb delete-item \
    --table-name User \
    --key '{"Name": {"S": "Satsumaimo"}, "Birthday": {"S": "1600-02-02"}}'
```
    
```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb delete-item \
>     --table-name User \
>     --key '{"Name": {"S": "Satsumaimo"}, "Birthday": {"S": "1600-02-02"}}'
```
    
削除されたことを確認します。（テーブルの全アイテムとアイテム属性を返す `scan` を実行します）

```bash
awslocal dynamodb scan --table-name User
```

```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb scan --table-name User
{
    "Items": [
        {
            "Birthday": {
                "S": "1600-01-01"
            },
            "Age": {
                "S": "423"
            },
            "Name": {
                "S": "Yamaimo"
            }
        },
        {
            "Birthday": {
                "S": "1986-06-28"
            },
            "Age": {
                "S": "36"
            },
            "Name": {
                "S": "Yamate"
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 2,
    "ConsumedCapacity": null
}
```
    

# 9. テーブルの削除 delete-table

テーブルを削除する `delete-table` を実行します。

```bash
awslocal dynamodb delete-table --table-name User
```

```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb delete-table --table-name User
{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "Name",
                "AttributeType": "S"
            },
            {
                "AttributeName": "Birthday",
                "AttributeType": "S"
            }
        ],
        "TableName": "User",
        "KeySchema": [
            {
                "AttributeName": "Name",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "Birthday",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1670995921.378,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 68,
        "ItemCount": 2,
        "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/User",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": 1670995921.378
        }
    }
}
```
  
テーブルが削除されたことを確認します。（テーブルをリスト表示する `list-tables` を実行します）

```bash
awslocal dynamodb list-tables
```    


```bash:実行時ログ
root@e4f2c4a95830:/opt/code/localstack# awslocal dynamodb list-tables
{
    "TableNames": []
}
```    

# おわりに

LocalStack で Amazon DynamoDB を動作させてみました。 AWS CLI の操作は初めてでしたが、 DynamoDB の基本操作については把握することができました。

記事をご覧いただき、ありがとうございました。

## 参考

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/WorkingWithTables.Basics.html

https://zenn.dev/marumarumeruru/articles/6aeb25bd27063a