Python (boto3) で DynamoDB を操作する - put_item()/get_item()
2019-03-04先日参加した AWS のハンズオンで DynamoDB を初めて触りました。そのときは Node.js で書かれたサンプルコードをコピペするだけで、データの読み/書きができました。 ということで、今回は Python でデータの読み/書きを実装してみたので、その時のメモです。
目次
テーブル作成
まずはテーブルを作成します。 今回は例として、欅坂46のメンバーブログの情報を保持するテーブルを作成してみます。あとでデータが取得しやすいように、 プライマリパーティションキー と プライマリソートキー は次のように設定します。
- プライマリパーティションキー :
Authorcode
(文字列) ・・・ ブログ記事を書いたメンバーのコード - プライマリソートキー :
Url
(文字列) ・・・ ブログ記事のURL
ブログの URL には自動採番された (であろう) 数値がパラメータとして付与されているので、 Url
でソートすれば実質投稿順となります。
データの登録 put_item()
登録するデータは、次のような json を想定します。
{
"Author": "欅坂46二期生",
"Authorcode": "1001",
"Entrydate": 20190224,
"Images": [
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c.jpg",
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-01.jpg",
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-02.jpg",
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-03.jpg",
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-04.jpg",
"http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-05.jpg"
],
"Title": "初歌番組。武元唯衣です。",
"Url": "http://www.keyakizaka46.com/s/k46o/diary/detail/19596?ima=0000&cd=member"
}
boto3 を使って DynamoDB にデータを登録するには put_item()
を使います。
import boto3
table_name = 'keyakizaka-blog'
item = {
'Author': '欅坂46二期生',
'Authorcode': '1001',
'Entrydate': 20190224,
'Images': [
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c.jpg',
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-01.jpg',
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-02.jpg',
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-03.jpg',
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-04.jpg',
'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-05.jpg'
],
'Title': '初歌番組。武元唯衣です。',
'Url': 'http://www.keyakizaka46.com/s/k46o/diary/detail/19596?ima=0000&cd=member'
}
dynamo = boto3.client('dynamodb')
dynamo.put_item(TableName=table_name, Item=item)
とすると登録できます。…と思っていましたが、これでは出来ません。
リファレンスを読めば書いてるんですが、Item
として指定する dict
型のオブジェクトの各項目に、それらの型が何なのかを、dict
型で指定する必要があります。例えば、上の例だと、 item
として次のようなオブジェクトを定義する必要があります。
item = {
'Author': {'S': '欅坂46二期生'},
'Authorcode': {'S': '1001'},
'Entrydate': {'N': '20190224'},
'Images': {'L': [
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c.jpg'},
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-01.jpg'},
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-02.jpg'},
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-03.jpg'},
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-04.jpg'},
{'S': 'http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-05.jpg'}
]},
'Title': {'S': '初歌番組。武元唯衣です。'},
'Url': {'S': 'http://www.keyakizaka46.com/s/k46o/diary/detail/19596?ima=0000&cd=member'}
}
上に出てきているものでは
- S: 文字列
- N: 数値
- L: リスト
のような感じです。リスト内の項目についても、それぞれ型の指定が必要です。
また、N
で数値を指定する際にも、数値ではなく文字列で値を定義する必要があります。上の例では Entrydate
の部分で 'Entrydate': {'N': 20190224},
ではなく 'Entrydate': {'N': '20190224'}
とします。
データの取得 get_item()
ここでいうデータの取得とは、単一のデータ取得です。 RDB の SELECT のような感じで複数データを取得する場合は query()
を使いますが、それはまた次回。
単一のデータを取得する get_item()
は、次のように使います。
import boto3
table_name = 'keyakizaka-blog'
dynamo = boto3.client('dynamodb')
res = dynamo.get_item(TableName=table_name, Key={
'Authorcode': {'S': '1001'},
'Url': {'S': 'http://www.keyakizaka46.com/s/k46o/diary/detail/19596?ima=0000&cd=member'}
})
データが存在していた場合は、下記のようなレスポンスが返ってきます。
{
"Item": {
"Title": {
"S": "初歌番組。武元唯衣です。"
},
"Authorcode": {
"S": "1001"
},
"Author": {
"S": "欅坂46二期生"
},
"Images": {
"L": [
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c.jpg"
},
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-01.jpg"
},
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-02.jpg"
},
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-03.jpg"
},
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-04.jpg"
},
{
"S": "http://cdn.keyakizaka46.com/images/14/91e/fd0a1b0dec088e270f545ce11bd3c-05.jpg"
}
]
},
"Entrydate": {
"N": "20190224"
},
"Url": {
"S": "http://www.keyakizaka46.com/s/k46o/diary/detail/19596?ima=0000&cd=member"
}
},
"ResponseMetadata": {
"RequestId": "CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXG",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"server": "Server",
"date": "Mon, 03 Mar 2019 05:23:22 GMT",
"content-type": "application/x-amz-json-1.0",
"content-length": "776",
"connection": "keep-alive",
"x-amzn-requestid": "CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXG",
"x-amz-crc32": "1759887117"
},
"RetryAttempts": 0
}
}
データが存在しなかった場合は、下記のようなレスポンスになるので、Item
キーの存在チェックでデータの存在チェックができます。
{
"ResponseMetadata": {
"RequestId": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXG",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"server": "Server",
"date": "Mon, 03 Mar 2019 05:25:51 GMT",
"content-type": "application/x-amz-json-1.0",
"content-length": "2",
"connection": "keep-alive",
"x-amzn-requestid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXG",
"x-amz-crc32": "2745614147"
},
"RetryAttempts": 0
}
}
まとめ
今回は boto3 の client.put_item() / client.get_item() を使いました。
ただ、どうやら以下のようにすることで Item
に普通の dict
を渡すことができるようです。
table_name = 'keyakizaka-blog'
dynamo = boto3.resource('dynamodb')
table = dynamo.Table('name')
table.put_item(Item={
/* ... */
})
また、複数のデータを登録する際には、DynamoDB の BatchWriteItem オペレーションを利用するのが良さそうです。
あと、今回プライマリソートキーには文字列を指定していますが、ここに指定するのは数値のほうが良い気もしています。 そのあたりも含めて、もうちょっと DynamoDB 触ってみたいと思います。
このほかにも、 boto3 を使って DynamoDB を操作してみた話を書いているので、参考にしてみてください。
comments powered by Disqus