awsのPython SDK "boto3"でDyanamoDBを操作する

boto3でDynamoDBを操作しようと思います。

AWS公式のtutorialでは、ec2を操作していますが、dynamodbいじるほうがおもしろそうなので、dynamoで。以下は前回のリンクです。

"Getting Started with AWS and Python"をboto3で試す その2 - goodbyegangsterのブログ

公式はこちら。

DynamoDB — Boto 3 Docs 1.6.19 documentation

こんなテーブルを作成します。Patition KeyとしてVoiceRoidName、Sort KeyとしてVoiceRoidNoを、Lover属性を利用してGrobal Secondary Indexを設定します。

VoiceRoidNo VoiceRoidName Age Lover
001 結月ゆかり 17 まきさん
002 弦巻マキ 17 ゆかりん
003 東北ずん子 17 ずんだ
004 琴葉茜 16
005 琴葉葵 16 おねえちゃん
006 東北きりたん 11 ずんねえさま
007 京町セイカ 22

とりあえず、dynamodbを利用できるServiceを用意して、テーブルを作成します。

> import boto3
> from boto3.dynamodb.conditions import Key, Attr

> dynamodb = boto3.resource('dynamodb')

> dynamodb.create_table(
...  AttributeDefinitions=[
...      {'AttributeName': 'VoiceRoidNo', 'AttributeType': 'N'},
...      {'AttributeName': 'VoiceRoidName', 'AttributeType': 'S'},
...      {'AttributeName': 'Lover', 'AttributeType': 'S'},
...  ],
...  TableName='VoiceRoid',
...  KeySchema=[
...      {'AttributeName': 'VoiceRoidName', 'KeyType': 'HASH'},
...      {'AttributeName': 'VoiceRoidNo', 'KeyType': 'RANGE'}
...  ],
...  GlobalSecondaryIndexes=[
...      {
...          'IndexName': 'idx_VoiceRoid_Lover',
...          'KeySchema': [
...              {'AttributeName': 'Lover', 'KeyType': 'HASH'}
...          ],
...          'Projection':{
...              'ProjectionType': 'ALL',
...          },
...          'ProvisionedThroughput': {
...              'ReadCapacityUnits': 3,
...              'WriteCapacityUnits': 3
...          }
...      }
...  ],
...  ProvisionedThroughput={
...      'ReadCapacityUnits': 3,
...      'WriteCapacityUnits': 3
...  }
...)

作成したテーブルにアイテムを追加します。

> table = dynamodb.Table('VoiceRoid')

> table.put_item(
...  Item={
...    'VoiceRoidName': '結月ゆかり',
...    'VoiceRoidNo': 1,
...    'Age': 17,
...    'Lover': 'まきさん'
...  }
...)

バッチ処理でputするのはこんな感じ。

> dynamodb.batch_write_item(
...  RequestItems={
...    'VoiceRoid': [
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '弦巻マキ', 'VoiceRoidNo': 2, 'Age': 17, 'Lover': 'ゆかりん'}
...        }
...      },
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '東北ずん子', 'VoiceRoidNo': 3, 'Age': 17, 'Lover': 'ずんだ'}
...        }
...      },
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '琴葉茜', 'VoiceRoidNo': 4, 'Age': 16}
...        }
...      },
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '琴葉葵', 'VoiceRoidNo': 5, 'Age': 16, 'Lover': 'おねえちゃん'}
...        }
...      },
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '東北きりたん', 'VoiceRoidNo': 5, 'Age': 11, 'Lover': 'ずんねえさま'}
...        }
...      },
...      {
...        'PutRequest':{
...          'Item': {'VoiceRoidName': '京町セイカ', 'VoiceRoidNo': 7, 'Age': 22}
...        }
...      },
...    ]
...  }
...)

読み取り処理ですね。

> res1 = table.get_item(
...  Key={
...    'VoiceRoidName': '結月ゆかり',
...    'VoiceRoidNo': 1,
...    'ConsistentRead'=True
...  }
...)

> print(res1['Item']['Lover'])
まきさん

Grobal Secondary Indexを利用したクエリ処理です。

> res2 = table.query(
...  IndexName='idx_VoiceRoid_Lover',
...  Select='ALL_PROJECTED_ATTRIBUTES',
...  ConsistentRead=False,
...  KeyConditionExpression=Key('Lover').eq('ずんねえさま')
...)

> print(res2['Items'][0]['VoiceRoidName'])
東北きりたん