使用Python操作Amazon DynamoDB:电影数据管理实战教程

使用Python操作Amazon DynamoDB:电影数据管理实战教程

aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. aws-doc-sdk-examples 项目地址: https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples

Amazon DynamoDB是一种完全托管的NoSQL数据库服务,提供快速且可预测的性能,能够实现无缝扩展。本文将通过一个电影数据管理的实战案例,演示如何使用Python SDK(Boto3)与DynamoDB进行交互。

1. 准备工作

首先需要安装必要的Python包:

import boto3
from boto3.dynamodb.conditions import Key
from decimal import Decimal
import json

2. 创建DynamoDB表

2.1 表结构设计

电影数据表的设计需要考虑以下因素:

  • 分区键(Partition Key):使用电影发行年份(year)
  • 排序键(Sort Key):使用电影标题(title)

这种设计允许我们:

  • 快速查询特定年份的电影
  • 精确获取某年某部电影的信息
def create_table(self, table_name):
    try:
        self.table = self.dyn_resource.create_table(
            TableName=table_name,
            KeySchema=[
                {"AttributeName": "year", "KeyType": "HASH"},  # 分区键
                {"AttributeName": "title", "KeyType": "RANGE"},  # 排序键
            ],
            AttributeDefinitions=[
                {"AttributeName": "year", "AttributeType": "N"},
                {"AttributeName": "title", "AttributeType": "S"},
            ],
            BillingMode='PAY_PER_REQUEST',
        )
        self.table.wait_until_exists()
    except ClientError as err:
        logger.error("创建表失败: %s", err)
        raise

3. 数据操作

3.1 批量写入数据

使用批量写入操作可以高效地加载大量数据:

def write_batch(self, movies):
    try:
        with self.table.batch_writer() as writer:
            for movie in movies:
                writer.put_item(Item=movie)
    except ClientError as err:
        logger.error("批量写入失败: %s", err)
        raise

3.2 添加单条记录

添加单部电影信息:

def add_movie(self, title, year, plot, rating):
    try:
        self.table.put_item(
            Item={
                "year": year,
                "title": title,
                "info": {"plot": plot, "rating": Decimal(str(rating))},
            }
        )
    except ClientError as err:
        logger.error("添加电影失败: %s", err)
        raise

4. 查询与扫描

4.1 精确查询

查询特定年份的电影:

def query_movies(self, year):
    try:
        response = self.table.query(KeyConditionExpression=Key("year").eq(year))
    except ClientError as err:
        logger.error("查询失败: %s", err)
        raise
    else:
        return response["Items"]

4.2 范围扫描

扫描特定年份范围内的电影:

def scan_movies(self, year_range):
    movies = []
    scan_kwargs = {
        "FilterExpression": Key("year").between(year_range["first"], year_range["second"]),
        "ProjectionExpression": "#yr, title, info.rating",
        "ExpressionAttributeNames": {"#yr": "year"},
    }
    try:
        done = False
        start_key = None
        while not done:
            if start_key:
                scan_kwargs["ExclusiveStartKey"] = start_key
            response = self.table.scan(**scan_kwargs)
            movies.extend(response.get("Items", []))
            start_key = response.get("LastEvaluatedKey", None)
            done = start_key is None
    except ClientError as err:
        logger.error("扫描失败: %s", err)
        raise
    return movies

5. 更新与删除

5.1 条件更新

更新电影评分和剧情简介:

def update_movie(self, title, year, rating, plot):
    try:
        response = self.table.update_item(
            Key={"year": year, "title": title},
            UpdateExpression="set info.rating=:r, info.plot=:p",
            ExpressionAttributeValues={":r": Decimal(str(rating)), ":p": plot},
            ReturnValues="UPDATED_NEW",
        )
    except ClientError as err:
        logger.error("更新失败: %s", err)
        raise
    else:
        return response["Attributes"]

5.2 删除记录

删除特定电影:

def delete_movie(self, title, year):
    try:
        self.table.delete_item(Key={"year": year, "title": title})
    except ClientError as err:
        logger.error("删除失败: %s", err)
        raise

6. 实战场景

6.1 交互式操作

通过命令行交互方式管理电影数据:

def run_scenario(table_name, movie_file_name, dyn_resource):
    movies = Movies(dyn_resource)
    if not movies.exists(table_name):
        movies.create_table(table_name)
    
    # 添加用户自定义电影
    my_movie = {
        "title": input("电影标题: "),
        "year": int(input("发行年份: ")),
        "rating": float(input("评分(1-10): ")),
        "plot": input("剧情简介: ")
    }
    movies.add_movie(**my_movie)
    
    # 查询示例
    if input("查询《指环王》信息?(y/n) ").lower() == 'y':
        movie = movies.get_movie("The Lord of the Rings: The Fellowship of the Ring", 2001)
        pprint(movie)

7. 最佳实践

  1. 合理设计主键:根据查询模式选择分区键和排序键
  2. 使用批量操作:减少API调用次数
  3. 适当使用投影:只检索需要的属性
  4. 处理大结果集:使用LastEvaluatedKey分页
  5. 错误处理:捕获并妥善处理ClientError

8. 总结

通过这个电影数据管理案例,我们学习了DynamoDB的基本操作,包括:

  • 表的创建与管理
  • 数据的增删改查
  • 查询与扫描操作
  • 条件更新与批量操作

这些技术可以应用于各种需要高性能、可扩展数据存储的场景,如用户配置存储、游戏状态管理、物联网数据处理等。

aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. aws-doc-sdk-examples 项目地址: https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦贝仁Lincoln

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值