この記事で書くこと
ローカル環境でdynamodb-localを利用する方法をなるべくシンプルに記載します。
手順は以下の通りです。
- dynamodb-localコンテナの起動とデータの永続化
- サンプルデータの投入
- データの永続化確認
- アプリケーションからの接続とリクエスト実行
背景
個人的に、RDBも含めてDBをDocker化することで以下のような利点を感じています。
- ローカル環境に各種DBの様々なバージョンを入れないことで管理しやすくなった
- アプリケーションの実行時には毎回dockerコマンドを打たなくてよくなった
同じように感じている、もしくはそのようにしたいという方の参考になればと思っています。
実行環境
OS:macOS Big Sur(version 11.6)
docker:20.10.0
aws-cli:1.20.53
python:3.9.1
boto3:1.18.48
dynamodb-localコンテナの起動とデータの永続化
下記公式サイトではdocker run
コマンドでの起動方法が書いてあります。
しかし、起動と終了が頻発することを想定し、今回はdocker-compose
を利用することにします。
ディレクトリ構成とyamlファイルは以下の通りです。
├ docker-compose.yaml
├ dynamodb_data // データ保存用のディレクトリ
├ api
│ └ create_table.json // テーブル作成用
│ └ input_data.json // input用データ
version: '3'
services:
dynamodb:
image: amazon/dynamodb-local
container_name: dynamodb_local
user: root
command: -jar DynamoDBLocal.jar -sharedDb -dbPath /data
volumes:
- ./dynamodb_data:/data
ports:
- 8000:8000
永続化にあたってのポイントは以下2点です。
-
user
でrootユーザー
を指定することで名前付きボリュームを利用可能にしている -
command
で-dbPath
を指定することでデータを永続化している
詳細な内容については下記の記事をご参照ください。
https://developers.freee.co.jp/entry/dynamodb-local
docker-compose
コマンドでイメージのpullからコンテナを起動まで一気に実施します。
$ docker-compose up -d
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
08c276a5b062 amazon/dynamodb-local "java -jar DynamoDBL…" 1 hours ago Up 23 hours 0.0.0.0:8000->8000/tcp dynamodb_local
サンプルデータの投入
用意しておいたcreate_table.json
を元にテーブル作成。
{
"AttributeDefinitions": [
{
"AttributeName": "name",
"AttributeType": "S"
}
],
"TableName": "students",
"KeySchema": [
{
"AttributeName": "name",
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
$ aws dynamodb create-table --cli-input-json file://settings/create_table.json --endpoint-url http://localhost:8000
--endpoint-url
を指定しないとローカルでないAWS上にリソースが作成されてしまう可能性があるのでご注意ください。
続いてinput_data.json
を元にデータも投入します。
{
"students": [
{
"PutRequest": {
"Item": {
"name": { "S": "ichiro" },
"hometown": { "S": "Tokyo" }
}
}
},
{
"PutRequest": {
"Item": {
"name": { "S": "jiro" },
"hometown": { "S": "Chiba" },
"hobby": {"S": "table tennis"}
}
}
},
{
"PutRequest": {
"Item": {
"name": { "S": "saburo" },
"hometown": { "S": "Kanagawa" }
}
}
}
]
}
$ aws dynamodb batch-write-item --request-items file://settings/input_data.json --endpoint-url http://localhost:8000
scan
(全表スキャン)して確認し、無事データが登録されているのを確認します。
$ aws dynamodb scan --table-name students --endpoint-url http://localhost:8000
{
"Items": [
{
"name": {
"S": "ichiro"
},
"hometown": {
"S": "Tokyo"
}
},
{
"name": {
"S": "saburo"
},
"hometown": {
"S": "Kanagawa"
}
},
{
"name": {
"S": "jiro"
},
"hometown": {
"S": "Chiba"
},
"hobby": {
"S": "table tennis"
}
}
],
"Count": 3,
"ScannedCount": 3,
"ConsumedCapacity": null
}
データの永続化確認
永続化の確認のためにdocker-compose down
とdocker-compose-up
を再度実行します。
$ docker-compose down
$ docker-compose up -d
先程と全く同じようにscan
してみるとそのまま3件数のデータが残っていることが確認できました。
{
"Items": [
{
"name": {
"S": "ichiro"
},
"age": {
"N": "22"
},
"hometown": {
"S": "Tokyo"
}
},
{
"name": {
"S": "saburo"
},
"age": {
"N": "20"
},
"hometown": {
"S": "Kanagawa"
}
},
{
"name": {
"S": "jiro"
},
"hometown": {
"S": "Chiba"
},
"age": {
"N": "21"
},
"hobby": {
"S": "table tennis"
}
}
],
"Count": 3,
"ScannedCount": 3,
"ConsumedCapacity": null
}
この状態を作成できればとりあえず安心して手元から操作できそうです。
アプリケーションからの接続
せっかくなのでアプリケーションからもscan
操作を実行してみます。
import boto3
def scan():
dynamodb = boto3.resource('dynamodb',
endpoint_url="http://localhost:8000",
region_name="us-west2", # ダミー情報です
aws_access_key_id="access_key_id", # ダミー情報です
aws_secret_access_key="secret_access_key" # ダミー情報です
)
table = dynamodb.Table("students")
res = table.scan()
for item in res['Items']:
print(item)
if __name__ == '__main__':
scan()
無事に接続してデータを取得することができました。
{'name': 'ichiro', 'hometown': 'Tokyo'}
{'name': 'saburo', 'hometown': 'Kanagawa'}
{'name': 'jiro', 'hometown': 'Chiba', 'hobby': 'table tennis'}
おわりに
普段はsam-localからdynamodb-localへ接続することが多いのですが、そこでもハマりポイントがあったので今度記事にしようと思います。