Amazon DynamoDB
入门指南 (API Version 2012-08-10)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

步骤 3:创建、读取、更新和删除项目

在此步骤中,您将对 Movies 表中的项目执行读写操作。

要了解有关数据读写的更多信息,请参阅 Amazon DynamoDB 开发人员指南 中的处理项目

步骤 3.1:创建新项目

在此步骤中,您将向 Movies 表中添加一个新项目。

  1. 将以下程序复制到名为 MoviesItemOps01.py 的文件中。

    Copy
    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.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 开发工具包使用 Decimal 类存储 DynamoDB 数字值。

  2. 键入以下命令以运行程序:

    python MoviesItemOps01.py

步骤 3.2:读取项目

在上一个程序中,您已向表中添加了以下项目:

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

您可以使用 get_item 方法读取 Movies 表中的项目。您必须指定主键值,以便在知道 Movies 中的任何项目的 yeartitle 的情况下读取该项目。

  1. 将以下程序复制到名为 MoviesItemOps02.py 的文件中。

    Copy
    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)的值。

  • 向现有 info 映射中添加新的列表属性 (actors)。

项目将在以下基础上进行更改:

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

更改为以下项目:

Copy
{ year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } }
  1. 将以下程序复制到名为 MoviesItemOps03.py 的文件中。

    Copy
    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 的文件中。

    Copy
    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。如果条件为真,则更新成功;否则,不执行更新。

在此示例中,仅当有超过 3 位男演员时,才会更新项目。

  1. 将以下程序复制到名为 MoviesItemOps05.py 的文件中。

    Copy
    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. 修改程序,以使 ConditionExpression 如下所示:

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

    此时,条件变成大于或等于 3,而不是大于 3

  4. 重新运行程序。UpdateItem 操作这次应该会成功。

步骤 3.6:删除项目

您可以使用 delete_item 方法,通过指定项目的主键来删除一个项目。您可以提供一个 ConditionExpression,避免在不符合条件时删除项目。

在以下示例中,您将尝试删除评分为 5 分或更低的特定电影项目。

  1. 将以下程序复制到名为 MoviesItemOps06.py 的文件中。

    Copy
    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 中的条件。

    Copy
    response = table.delete_item( Key={ 'year': year, 'title': title } )
  4. 运行程序。因为您已移除条件,所以此时删除操作将会成功。