Amazon DynamoDB
開発者ガイド (API バージョン 2012-08-10)

ステップ 3: 項目を作成、読み込み、更新、削除する

このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。

データの読み書きに関する詳細については、「DynamoDB での項目の操作」を参照してください。

ステップ 3.1: 新しい項目を作成する

このステップでは、Movies テーブルに新しい項目を追加します。

  1. 次のプログラムを MoviesItemOps01.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if abs(o) % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.put_item( Item={ 'year': year, 'title': title, 'info': { 'plot':"Nothing happens at all.", 'rating': decimal.Decimal(0) } } ) print("PutItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder))

    注記

    • プライマリキーは必須です。このコードは、プライマリキー (yeartitle) と info 属性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すサンプル JSON が保存されます。

    • DecimalEncoder クラスは、Decimal クラスを使用して保存された数値を出力するために使用されます。Boto SDK は、Decimal クラスを使用して DynamoDB の数値を保持します。

  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps01.py

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

前のプログラムでは、テーブルに次の項目を追加しました。

{ year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } }

get_item テーブルから項目を読み取る、Movies メソッドを使用できます。プライマリキー値を指定する必要があります。そうすると Moviesyear がわかれば、title から項目を読み込むことができます。

  1. 次のプログラムを MoviesItemOps02.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr from botocore.exceptions import ClientError # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource("dynamodb", region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 try: response = table.get_item( Key={ 'year': year, 'title': title } ) except ClientError as e: print(e.response['Error']['Message']) else: item = response['Item'] print("GetItem succeeded:") print(json.dumps(item, indent=4, cls=DecimalEncoder))
  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps02.py

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

update_item メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性の追加、または属性の削除を行えます。

このチュートリアルでは、次の更新を行います。

  • 既存の属性の値を変更します (ratingplot)。

  • 新しいリスト属性 (actors) を既存の info マップに追加します。

項目の変更前:

{ year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } }

項目の変更後:

{ year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } }
  1. 次のプログラムを MoviesItemOps03.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="set info.rating = :r, info.plot=:p, info.actors=:a", ExpressionAttributeValues={ ':r': decimal.Decimal(5.5), ':p': "Everything happens all at once.", ':a': ["Larry", "Moe", "Curly"] }, ReturnValues="UPDATED_NEW" ) print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder))

    注記

    このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべての更新を記述します。

    ReturnValues パラメーターは、DynamoDB に更新された属性 (UPDATED_NEW) のみを返すように指示します。

  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps03.py

ステップ 3.4: アトミックカウンターを増分する

DynamoDB では、アトミックカウンターがサポートされています。そのため、update_item メソッドを使用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデクリメントできます。(すべての書き込みリクエストは、受信された順に適用されます。)

次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムはこの属性を 1 つ増分します。

  1. 次のプログラムを MoviesItemOps04.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="set info.rating = info.rating + :val", ExpressionAttributeValues={ ':val': decimal.Decimal(1) }, ReturnValues="UPDATED_NEW" ) print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder))
  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps04.py

ステップ 3.5: 項目を更新する (条件付き)

次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価された場合、更新は成功します。それ以外の場合、更新は行われません。

この場合、項目は役者が 4 人以上いる場合にのみ更新されます。

  1. 次のプログラムを MoviesItemOps05.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 from botocore.exceptions import ClientError import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 # Conditional update (will fail) print("Attempting conditional update...") try: response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="remove info.actors[0]", ConditionExpression="size(info.actors) > :num", ExpressionAttributeValues={ ':num': 3 }, ReturnValues="UPDATED_NEW" ) except ClientError as e: if e.response['Error']['Code'] == "ConditionalCheckFailedException": print(e.response['Error']['Message']) else: raise else: print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder))
  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps05.py

    プログラムは次のメッセージで失敗するはずです。

    The conditional request failed

    これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしているためです。

  3. ConditionExpression が次のようになるようにプログラムを変更します。

    ConditionExpression="size(info.actors) >= :num",

    条件が、3 より大きいではなく 3 以上になりました。

  4. プログラムを再度実行します。これで、UpdateItem オペレーションが成功します。

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

プライマリキーを指定することで、delete_item メソッドを使用して 1 つの項目を削除できます。オプションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐことができます。

次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。

  1. 次のプログラムを MoviesItemOps06.py というファイルにコピーアンドペーストします。

    # # Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. # from __future__ import print_function # Python 2/3 compatibility import boto3 from botocore.exceptions import ClientError import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 print("Attempting a conditional delete...") try: response = table.delete_item( Key={ 'year': year, 'title': title }, ConditionExpression="info.rating <= :val", ExpressionAttributeValues= { ":val": decimal.Decimal(5) } ) except ClientError as e: if e.response['Error']['Code'] == "ConditionalCheckFailedException": print(e.response['Error']['Message']) else: raise else: print("DeleteItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder))
  2. このプログラムを実行するには、次のコマンドを入力します。

    python MoviesItemOps06.py

    プログラムは次のメッセージで失敗するはずです。

    The conditional request failed

    これは、この特定の映画のレーティングが 5 より大きいためです。

  3. table.delete_item で条件を削除するようにプログラムを変更します。

    response = table.delete_item( Key={ 'year': year, 'title': title } )
  4. プログラムを実行します。ここでは、条件を削除したため、削除が成功します。