Symfoware

Symfowareについての考察blog

DynamoDB LocalにPython(boto3)でテーブルの作成、データの登録

DynamoDBのデバッグ用サーバー「DynamoDB Local」を動かしてみました。
Ubuntu 18.04でDynamoDB Localを動作させる

Python + boto3でテーブルの作成やデータの登録を試してみます。


boto3のインストール



boto3はpipでインストールしました。


$ pip3 install boto3





ステップ 1: テーブルを作成する



こちらのチュートリアルを参考に写経していきます。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.01.html

テーブルを作成するプログラムはこうなりました。


  1. # -*- coding:utf-8 -*-
  2. import boto3
  3. dynamodb = boto3.resource(
  4.     'dynamodb',
  5.     region_name='ap-northeast-1.',
  6.     endpoint_url="http://192.168.1.102:8000",
  7.     aws_access_key_id='ACCESS_ID',
  8.     aws_secret_access_key='ACCESS_KEY'
  9. )
  10. table = dynamodb.create_table(
  11.     TableName='Movies',
  12.     KeySchema=[
  13.         {
  14.             'AttributeName': 'year',
  15.             'KeyType': 'HASH' #Partition key
  16.         },
  17.         {
  18.             'AttributeName': 'title',
  19.             'KeyType': 'RANGE' #Sort key
  20.         }
  21.     ],
  22.     AttributeDefinitions=[
  23.         {
  24.             'AttributeName': 'year',
  25.             'AttributeType': 'N'
  26.         },
  27.         {
  28.             'AttributeName': 'title',
  29.             'AttributeType': 'S'
  30.         },
  31.     ],
  32.     ProvisionedThroughput={
  33.         'ReadCapacityUnits': 10,
  34.         'WriteCapacityUnits': 10
  35.     }
  36. )
  37. print("Table status:", table.table_status)




ローカルのDynamoDBに対して実行するので、
・region_name
・aws_access_key_id
・aws_secret_access_key
これらの項目は本来不要なのですが、boto3が要求するので、適当な値を入れておきます。

ちなみに、region_nameを指定しなかった場合は、


botocore.exceptions.NoRegionError: You must specify a region.



aws_access_key_id、aws_secret_access_keyを指定しなかった場合は、


botocore.exceptions.NoCredentialsError: Unable to locate credentials



このようなエラーが発生します。

プログラムを実行すると、「Table status: ACTIVE」という応答が得られました。


$ python3 sample.py
Table status: ACTIVE



awsコマンドでも確認してみます。


$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Movies"
    ]
}



テーブルが作成されていることが確認できました。



ステップ 2: サンプルデータをロードする



https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.02.html

サンプルでは、ファイルを読み込んでデータを登録していますが、
1件だけ登録するプログラムに変更しました。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. year = 2013
  13. title = 'Turn It Down, Or Else!'
  14. info = {
  15.     'directors' : [
  16.         'Alice Smith',
  17.         'Bob Jones'
  18.     ],
  19.     'release_date' : '2013-01-18T00:00:00Z',
  20.     'rating' : decimal.Decimal('6.2'),
  21.     'genres' : [
  22.         'Comedy',
  23.         'Drama'
  24.     ],
  25.     'image_url' : 'http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg',
  26.     'plot' : 'A rock band plays their music at high volumes, annoying the neighbors.',
  27.     'rank' : 11,
  28.     'running_time_secs' : 5215,
  29.     'actors' : [
  30.         'David Matthewman',
  31.         'Ann Thomas',
  32.         'Jonathan G. Neff'
  33.     ]
  34. }
  35. table.put_item(
  36.     Item={
  37.         'year': year,
  38.         'title': title,
  39.         'info': info,
  40.     }
  41. )



ポイントは、小数点を含む値の登録。
何も考えずfloat値を指定すると、以下のエラーが発生します。


TypeError: Float types are not supported. Use Decimal types instead.



こちらを参考に、Decimalに変換して指定してやります。
How can I store 30.40 in DynamoDb?




ステップ 3.2: 項目を読み取る



>https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html

登録したデータを検索してみます。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.get_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         }
  20.     )
  21. except ClientError as e:
  22.     print(e.response['Error']['Message'])
  23. else:
  24.     item = response['Item']
  25.     print('GetItem succeeded:')
  26.     print(item)




実行結果です。
(json部分は整形しています)


$ python3 sample.py
GetItem succeeded:
{
    'title': 'Turn It Down, Or Else!',
    'year': Decimal('2013'),
    'info': {
        'actors': ['David Matthewman', 'Ann Thomas', 'Jonathan G. Neff'],
        'release_date': '2013-01-18T00:00:00Z',
        'plot': 'A rock band plays their music at high volumes, annoying the neighbors.',
        'genres': ['Comedy', 'Drama'],
        'image_url': 'http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg',
        'directors': ['Alice Smith', 'Bob Jones'],
        'rating': Decimal('6.2'),
        'rank': Decimal('11'),
        'running_time_secs': Decimal('5215')
    }
}






ステップ 3.3: 項目を更新する




  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.update_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         },
  20.         UpdateExpression='set info.image_url = :url, info.rating=:rate',
  21.         ExpressionAttributeValues={
  22.             ':url' : 'https://www.example.com/image.jpg',
  23.             ':rate' : decimal.Decimal('8.2')
  24.         },
  25.         ReturnValues='UPDATED_NEW'
  26.     )
  27. except ClientError as e:
  28.     print(e.response['Error']['Message'])
  29. else:
  30.     #item = response['Item']
  31.     item = response
  32.     print('UpdateItem succeeded:')
  33.     print(item)



UpdateExpressionで、更新の条件式を指定。
ExpressionAttributeValuesで、条件式に渡す値を設定。
...という流れのようです。

実行すると、こんな結果が帰ってきました。
ちゃんと値が更新されています。





ステップ 3.6: 項目を削除する



ちょっと飛ばして、データの削除。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.delete_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         }
  20.     )
  21. except ClientError as e:
  22.     print(e.response['Error']['Message'])
  23. else:
  24.     #item = response['Item']
  25.     item = response
  26.     print('DeleteItem succeeded:')
  27.     print(item)



実行結果


$ python3 sample.py
DeleteItem succeeded:
{'ResponseMetadata': {
    'RequestId': '6c75f576-7b6c-4590-a1c7-242ed4beee36',
    'HTTPStatusCode': 200,
    'HTTPHeaders': {
        'content-type': 'application/x-amz-json-1.0',
        'x-amz-crc32': '2745614147',
        'x-amzn-requestid': '6c75f576-7b6c-4590-a1c7-242ed4beee36',
        'content-length': '2',
        'server': 'Jetty(8.1.12.v20130726)'
    },
    'RetryAttempts': 0
}}





ステップ 5: (オプション) テーブルを削除する



https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.05.html

最初に作成したMovieテーブルを削除します。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. table.delete()



awsコマンドで確認します。


$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": []
}




次は、今回飛ばした
・ステップ 3.4: アトミックカウンターを増分する
・ステップ 3.5: 項目を更新する (条件付き)
・ステップ 4: データをクエリおよびスキャンする
を試してみようと思います。

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/24(日) 19:29:39|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<DynamoDB データのインクリメント、デクリメント(アトミックカウンター) | ホーム | Ubuntu 18.04でDynamoDB Localを動作させる>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
https://symfoware.blog.fc2.com/tb.php/2208-f80c33f5
この記事にトラックバックする(FC2ブログユーザー)