DynamoDB LocalでgetItemしたら、ResourceNotFoundException: Cannot do operations on a non-existent table が返ってきた

状況

ホスト側のターミナルから見た、DynamoDb LocalのURLは、http://localhost:5003です。

ホスト側のターミナルで、aws dynamodbコマンドを使って、create-table、put-item、get-itemしました。問題ありません。

別のDockerコンテナでwebサーバを走らせています。そのwebサーバから見た、DynamoDb LocalのURLは、http://dynamodb.container:8000です。

そのWebサーバから、DynamoDB LocalへgetItemしたところ、テーブルがないよ、とエラーになってしまいました。

Error executing "GetItem" on "http://dynamodb.container:8000"; AWS HTTP error: Client error: POST http://dynamodb.container:8000 resulted in a 400 Bad Request response: {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent (truncated…) ResourceNotFoundException (client): Cannot do operations on a non-existent table - {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent table"}

解決方法

ホスト側のターミナルで作業するときのAWS_ACCESS_KEY_IDとリージョン、Dockerコンテナのwebサーバに渡すAWS_ACCESS_KEY_IDとリージョンを同じにします。

ホスト側のターミナル

Dynamo DB LocalのAWS_ACCESS_KEY_IDとリージョンは任意です。仮に、次のようにします。

AWS_ACCESS_KEY_ID=hoge
リージョン=local

任意なので、リージョン=ap-northeast-1 にしても問題ありません。

ホスト側のターミナルでaws dynamodbコマンドを打つ前に、AWS_ACCESS_KEY_IDを設定します。

$ export AWS_ACCESS_KEY_ID=hoge $ export AWS_SECRET_ACCESS_KEY=hogehoge

Dynamo DB Localへaws dynamodbコマンドを打つとき、--region オプションでリージョンを指定します。

$ aws dynamodb --region local --endpoint-url http://localhost:5003 --table-name myapp_mytable 〜省略

Dockerコンテナのwebサーバ側

Dockerコンテナに渡すための環境変数の設定ファイルを作ります。ファイル名は、web.envとします。

AWS_ACCESS_KEY_ID=hoge AWS_SECRET_ACCESS_KEY=secret

docker-compose.ymlでenv_fileを記述します。

web: env_file: - ./web.env

PHPの場合、AwsSdkコンストラクタで、'region'を'local'にします。

$sdk = new AwsSdk([ 'endpoint' => 'http://dynamodb.container:8000', 'region' => 'local', 'version' => 'latest' ]);

DynamoDB Localのデータファイル

docker-compose.ymlで、Dockerコンテナを停止してもデータが消えないように、dbPathを設定し、Dockerコンテナの/home/dynamodblocal/dataをホスト側のディレクトリに外部マウントしました。

dynamodb: tty: true container_name: dynamodb.container image: amazon/dynamodb-local ports: - 5003:8000 command: -jar DynamoDBLocal.jar -dbPath ./data volumes: - ./dynamodb/data:/home/dynamodblocal/data

すると、ローカルの ./dynamo/data/ 下に、DynamoDB Localのデータファイルが見えるようになります。

いろいろ試したので、いくつかのファイルができています。

$ ls -1 ./dynamodb/data AK******************_ap-northeast-1.db AK******************_local.db hoge_ap-northeast-1.db hoge_local.db

つまり、[AWSアカウントID]_[リージョン].db で、分かれて保存されるんですね。

ターミナルから、AWS_ACCESS_KEY_ID=AK****、リージョン=ap-northeast-1で、テーブル作成すると、AK****_ap-northeast-1.db が作られます。

Dockerコンテナのwebサーバから、AWS_ACCESS_KEY_ID=hoge、リージョン=localで、getItemすると、hoge_local.db を読もうとします。

そのため、テーブルがないよ、とエラーになったんですね。

タイトルとURLをコピーしました