AWS CLI v2でDynamoDBのハイレベルコマンドを試してみた #reinvent
はじめに
中山(順)です
AWS CLI v2が開発中なのは皆さんご存じでしょうか?
今回のre:Inventでも紹介セッションが実施されました。
その際に、DynamoDBのハイレベルコマンドのデモが行われていました。 AWS CLIのコマンドは基本的にAPIと1:1に対応しています。 ただし、例外的にs3のハイレベルコマンドだけ提供されていました。 これが非常に使い勝手が良く、重宝していました。
v2で登場するDynamoDBも便利そうなのでちょっと使ってみました。
やってみた
今回はAmazon Linux (1)上で実施してみました。
インストール
以下のコマンドでインストールします。
sudo pip install -e git://github.com/aws/aws-cli.git@v2#egg=awscli
バージョンを確認します。
aws --version
aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48
コマンドの確認
DynamoDBのハイレベルコマンドは"ddb"です。ヘルプを確認してみます。
aws ddb help
DDB() DDB() NAME ddb - DESCRIPTION High level DynamoDB commands. See 'aws help' for descriptions of global parameters. SYNOPSIS aws ddb <Command> [<Arg> ...] OPTIONS None See 'aws help' for descriptions of global parameters. AVAILABLE COMMANDS o put o select DDB()
"select"と"put"の2つのコマンドが用意されています。
テーブルの作成
まずは検証用のテーブルを作成します。 コマンドはコマンドリファレンスのサンプルを拝借します。
aws dynamodb create-table \ --table-name MusicCollection \ --attribute-definitions AttributeName=Artist,AttributeType=S AttributeName=SongTitle,AttributeType=S \ --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \ --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
{ "TableDescription": { "TableArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/MusicCollection", "AttributeDefinitions": [ { "AttributeName": "Artist", "AttributeType": "S" }, { "AttributeName": "SongTitle", "AttributeType": "S" } ], "ProvisionedThroughput": { "NumberOfDecreasesToday": 0, "WriteCapacityUnits": 1, "ReadCapacityUnits": 1 }, "TableSizeBytes": 0, "TableName": "MusicCollection", "TableStatus": "CREATING", "TableId": "8b9c9b82-7a36-4e84-a09c-9d43bb24777a", "KeySchema": [ { "KeyType": "HASH", "AttributeName": "Artist" }, { "KeyType": "RANGE", "AttributeName": "SongTitle" } ], "ItemCount": 0, "CreationDateTime": "2018-11-30T09:17:43.920000+00:00" } }
実行履歴の取得を有効化
後で実行履歴を確認するため、有効化します。
aws configure set cli_history enabled
書き込み
書き込みは以下のように行います。 詳細はヘルプをご確認ください。
aws ddb put MusicCollection '{Artist: "No One You Know", SongTitle: "Call Me Today", AlbumTitle: "Somewhat Famous"}'
aws ddb put MusicCollection '{Artist: "Obscure Indie Band", SongTitle: "Atlas"}' \ --condition 'attribute_not_exists(Artist)'
参照
参照は以下のように行います。
全件をスキャンする場合は以下の通りです。
aws ddb select MusicCollection
Count: 2 Items: - Artist: Obscure Indie Band SongTitle: Atlas - AlbumTitle: Somewhat Famous Artist: No One You Know SongTitle: Call Me Today ScannedCount: 2
スキャンした結果の絞り込みは以下のように行います。
aws ddb select MusicCollection --projection 'SongTitle, AlbumTitle' \ --filter 'Artist = "No One You Know"'
Count: 1 Items: - AlbumTitle: Somewhat Famous SongTitle: Call Me Today ScannedCount: 2
クエリは以下のように行います。
aws ddb select MusicCollection --projection SongTitle \ --key-condition 'Artist = "No One You Know"'
Count: 1 Items: - SongTitle: Call Me Today ScannedCount: 1
実行履歴の確認
一覧は以下のように確認できます。 一覧では、コマンドID/時刻/コマンド(パラメーター無し)しか確認できません。
aws history list
414fadc6-f609-40c1-ba04-1c160ddfb7cc 2018-11-30 09:36:56 AM ddb select 0 366e9b1b-1169-4b88-8a51-52b520c7383f 2018-11-30 09:36:47 AM ddb select 0 be1168ca-0f75-4e85-bb3e-661266e7d9b8 2018-11-30 09:36:39 AM ddb put 0 8f2fb791-d6a6-4723-b255-9c4d5a4bc0c8 2018-11-30 09:36:34 AM ddb put 0 d638a10b-6dd8-4e37-8978-ae445616e53c 2018-11-30 09:36:25 AM dynamodb create-table 0
各実行履歴の確認は以下のように行います。 コマンドIDを指定して詳細を確認します。 以下の通り、実体はPutItemのAPIをコールしていることがわかります。
aws history show 8f2fb791-d6a6-4723-b255-9c4d5a4bc0c8
AWS CLI command entered at time: 2018-11-30 09:36:34.182 with AWS CLI version: aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48 with arguments: [u'ddb', u'put', u'MusicCollection', u'{Artist: "No One You Know", SongTitle: "Call Me Today", AlbumTitle: "Somewhat Famous"}'] [0] API call made at time: 2018-11-30 09:36:34.261 to service: dynamodb using operation: PutItem with parameters: { "Item": { "AlbumTitle": { "S": "Somewhat Famous" }, "Artist": { "S": "No One You Know" }, "SongTitle": { "S": "Call Me Today" } }, "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP request sent at time: 2018-11-30 09:36:34.270 to URL: https://dynamodb.us-east-1.amazonaws.com/ with method: POST with headers: { "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20181130/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token;x-amz-target , Signature=3546...", "Content-Length": "189", "Content-Type": "application/x-amz-json-1.0", "User-Agent": "aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48", "X-Amz-Date": "20181130T093634Z", "X-Amz-Security-Token": "xxx", "X-Amz-Target": "DynamoDB_20120810.PutItem" } with body: { "Item": { "AlbumTitle": { "S": "Somewhat Famous" }, "Artist": { "S": "No One You Know" }, "SongTitle": { "S": "Call Me Today" } }, "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP response received at time: 2018-11-30 09:36:34.319 with status code: 200 with headers: { "Connection": "keep-alive", "Content-Length": "2", "Content-Type": "application/x-amz-json-1.0", "Date": "Fri, 30 Nov 2018 09:36:34 GMT", "Server": "Server", "x-amz-crc32": "2745614147", "x-amzn-RequestId": "6TDKTJ4PDE2NKEQHBR82NI2RTJVV4KQNSO5AEMVJF66Q9ASUAAJG" } with body: {} [0] HTTP response parsed at time: 2018-11-30 09:36:34.326 parsed to: { "ResponseMetadata": { "HTTPHeaders": { "connection": "keep-alive", "content-length": "2", "content-type": "application/x-amz-json-1.0", "date": "Fri, 30 Nov 2018 09:36:34 GMT", "server": "Server", "x-amz-crc32": "2745614147", "x-amzn-requestid": "6TDKTJ4PDE2NKEQHBR82NI2RTJVV4KQNSO5AEMVJF66Q9ASUAAJG" }, "HTTPStatusCode": 200, "RequestId": "6TDKTJ4PDE2NKEQHBR82NI2RTJVV4KQNSO5AEMVJF66Q9ASUAAJG" } } AWS CLI command exited at time: 2018-11-30 09:36:34.329 with return code: 0
スキャンの場合は以下のような感じです。
aws history show 366e9b1b-1169-4b88-8a51-52b520c7383f
AWS CLI command entered at time: 2018-11-30 09:36:47.567 with AWS CLI version: aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48 with arguments: [u'ddb', u'select', u'MusicCollection'] [0] API call made at time: 2018-11-30 09:36:47.648 to service: dynamodb using operation: Scan with parameters: { "ConsistentRead": true, "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP request sent at time: 2018-11-30 09:36:47.653 to URL: https://dynamodb.us-east-1.amazonaws.com/ with method: POST with headers: { "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20181130/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token;x-amz-target , Signature=7803...", "Content-Length": "90", "Content-Type": "application/x-amz-json-1.0", "User-Agent": "aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48", "X-Amz-Date": "20181130T093647Z", "X-Amz-Security-Token": "xxxx", "X-Amz-Target": "DynamoDB_20120810.Scan" } with body: { "ConsistentRead": true, "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP response received at time: 2018-11-30 09:36:47.714 with status code: 200 with headers: { "Connection": "keep-alive", "Content-Length": "208", "Content-Type": "application/x-amz-json-1.0", "Date": "Fri, 30 Nov 2018 09:36:47 GMT", "Server": "Server", "x-amz-crc32": "2411811827", "x-amzn-RequestId": "4FKMC96OQFABKRJAO5OBAS2Q4RVV4KQNSO5AEMVJF66Q9ASUAAJG" } with body: { "Count": 2, "Items": [ { "Artist": { "S": "Obscure Indie Band" }, "SongTitle": { "S": "Atlas" } }, { "AlbumTitle": { "S": "Somewhat Famous" }, "Artist": { "S": "No One You Know" }, "SongTitle": { "S": "Call Me Today" } } ], "ScannedCount": 2 } [0] HTTP response parsed at time: 2018-11-30 09:36:47.717 parsed to: { "Count": 2, "Items": [ { "Artist": { "S": "Obscure Indie Band" }, "SongTitle": { "S": "Atlas" } }, { "AlbumTitle": { "S": "Somewhat Famous" }, "Artist": { "S": "No One You Know" }, "SongTitle": { "S": "Call Me Today" } } ], "ResponseMetadata": { "HTTPHeaders": { "connection": "keep-alive", "content-length": "208", "content-type": "application/x-amz-json-1.0", "date": "Fri, 30 Nov 2018 09:36:47 GMT", "server": "Server", "x-amz-crc32": "2411811827", "x-amzn-requestid": "4FKMC96OQFABKRJAO5OBAS2Q4RVV4KQNSO5AEMVJF66Q9ASUAAJG" }, "HTTPStatusCode": 200, "RequestId": "4FKMC96OQFABKRJAO5OBAS2Q4RVV4KQNSO5AEMVJF66Q9ASUAAJG" }, "ScannedCount": 2 } AWS CLI command exited at time: 2018-11-30 09:36:47.724 with return code: 0
クエリの結果は以下のような感じです。
aws history show eef26433-d3de-49f8-8409-3f4e6b943647
AWS CLI command entered at time: 2018-11-30 10:00:50.420 with AWS CLI version: aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48 with arguments: [u'ddb', u'select', u'MusicCollection', u'--projection', u'SongTitle', u'--key-condition', u'Artist = "No One You Know"'] [0] API call made at time: 2018-11-30 10:00:50.497 to service: dynamodb using operation: Query with parameters: { "ConsistentRead": true, "ExpressionAttributeNames": { "#n0": "SongTitle", "#n1": "Artist" }, "ExpressionAttributeValues": { ":n2": { "S": "No One You Know" } }, "KeyConditionExpression": "#n1 = :n2", "ProjectionExpression": "#n0", "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP request sent at time: 2018-11-30 10:00:50.502 to URL: https://dynamodb.us-east-1.amazonaws.com/ with method: POST with headers: { "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20181130/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token;x-amz-target, Signature=caa3...", "Content-Length": "291", "Content-Type": "application/x-amz-json-1.0", "User-Agent": "aws-cli/2.0.0dev0 Python/2.7.14 Linux/4.14.77-70.59.amzn1.x86_64 botocore/1.12.48", "X-Amz-Date": "20181130T100050Z", "X-Amz-Security-Token": "xxxx", "X-Amz-Target": "DynamoDB_20120810.Query" } with body: { "ConsistentRead": true, "ExpressionAttributeNames": { "#n0": "SongTitle", "#n1": "Artist" }, "ExpressionAttributeValues": { ":n2": { "S": "No One You Know" } }, "KeyConditionExpression": "#n1 = :n2", "ProjectionExpression": "#n0", "ReturnConsumedCapacity": "NONE", "TableName": "MusicCollection" } [0] HTTP response received at time: 2018-11-30 10:00:50.542 with status code: 200 with headers: { "Connection": "keep-alive", "Content-Length": "74", "Content-Type": "application/x-amz-json-1.0", "Date": "Fri, 30 Nov 2018 10:00:50 GMT", "Server": "Server", "x-amz-crc32": "2190602160", "x-amzn-RequestId": "H3RUHQC8FHOKBFM8KGRIN1FNR7VV4KQNSO5AEMVJF66Q9ASUAAJG" } with body: { "Count": 1, "Items": [ { "SongTitle": { "S": "Call Me Today" } } ], "ScannedCount": 1 } [0] HTTP response parsed at time: 2018-11-30 10:00:50.546 parsed to: { "Count": 1, "Items": [ { "SongTitle": { "S": "Call Me Today" } } ], "ResponseMetadata": { "HTTPHeaders": { "connection": "keep-alive", "content-length": "74", "content-type": "application/x-amz-json-1.0", "date": "Fri, 30 Nov 2018 10:00:50 GMT", "server": "Server", "x-amz-crc32": "2190602160", "x-amzn-requestid": "H3RUHQC8FHOKBFM8KGRIN1FNR7VV4KQNSO5AEMVJF66Q9ASUAAJG" }, "HTTPStatusCode": 200, "RequestId": "H3RUHQC8FHOKBFM8KGRIN1FNR7VV4KQNSO5AEMVJF66Q9ASUAAJG" }, "ScannedCount": 1 } AWS CLI command exited at time: 2018-11-30 10:00:50.552 with return code: 0
AWS CLI (v1)の時はどうだったか?
以下のようにコマンドを実行する必要があり、v2のハイレベルコマンドが気軽にDynamoDBのデータ操作ができるようになっていることがわかると思います。 先ほどの実行履歴の"[0] HTTP request sent"の"with body"部分でAPIコール時のパラメーターを確認できます。
aws dynamodb put-item \ --table-name MusicCollection \ --item file://item.json \ --return-consumed-capacity TOTAL
aws dynamodb scan \ --table-name MusicCollection \ --filter-expression "Artist = :a" \ --projection-expression "#ST, #AT" \ --expression-attribute-names file://expression-attribute-names.json \ --expression-attribute-values file://expression-attribute-values.json
aws dynamodb query \ --table-name MusicCollection \ --projection-expression "SongTitle" \ --key-condition-expression "Artist = :v1" \ --expression-attribute-values file://expression-attributes.json
まとめ
DynamoDBのデータ操作をCLIで気軽に行いたいとき、これまではコマンドの実行が少々面倒できたがハイレベルコマンドを利用することで簡単に操作できるようになりました。 機会があれば試してみましょう。
現場からは以上です。