- 示例工程
- 教程
- 后端
【免费下载链接】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.
导读
本文基于当前仓库中的 rustv1/examples/dynamodb/README.md 展开,系统讲解如何使用 AWS SDK for Rust 与 Amazon DynamoDB 交互。你将学会:创建按需计费(on-demand)表、写入/删除条目、分页列举表与扫描表内容、基于主键的 Query 查询,以及两个完整的实战场景——覆盖本地 DynamoDB 实例的连接、和用 PartiQL 原生 SQL 语法完成增删改查。文中所有代码示例均可在仓库中直接运行与测试,既适合初学者入门,也适合开发者快速复用现成代码片段。
一、示例概览与适用前提
该示例模块位于仓库的 rustv1/examples/dynamodb 目录,展示了如何通过 AWS SDK for Rust 调用 DynamoDB 的各项核心操作。DynamoDB 是 AWS 提供的全托管 NoSQL 数据库服务,以"快速、可预测的性能与无缝扩展"著称,开发者无需管理底层基础设施即可获得亚毫秒级的读写体验。
1.1 环境准备(Prerequisites)
在运行本模块示例之前,需要先完成 rustv1 目录下的通用前置条件,具体说明见 rustv1/README.md,核心要求包括:
- 拥有一个 AWS 账户,并按 AWS SDK for Rust 入门指南 配置好默认凭证(credentials)与默认 Region;
- 安装 Cargo 构建工具(通常随 rustup 一起安装);
- 理解
RUST_LOG环境变量的作用。本模块使用tracing_subscriber与env_filter打印结构化日志,可通过RUST_LOG精细控制日志级别:info:显示程序运行时的常规输出;{crate_name}=debug:显示每个操作的部分细节;aws_smithy_http_tower::dispatch=trace:打印每次 AWS SDK 调用的完整 HTTP 请求;aws_smithy_http::middleware=trace:打印每次调用的完整 HTTP 响应。
SDK 还支持通过环境变量配置行为,常用变量包括AWS_REGION(或AWS_DEFAULT_REGION)、AWS_PROFILE、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY等,这些均与 AWS CLI 兼容。
1.2 ⚠ 重要注意事项
运行本模块代码前务必了解以下三点(均来自原文档,仓库中亦有对应体现):
- 可能产生费用:运行这些代码可能导致您的 AWS 账户产生费用,详情参考 AWS Pricing 与 Free Tier;
- 运行测试同样可能产生费用:尤其涉及真实 AWS 资源的集成测试;
- 遵循最小权限原则:建议为代码授予最小权限(Least Privilege),仅提供完成任务所需的最低权限,详见 Grant least privilege;
- 区域可用性:这些代码未经所有 AWS 区域测试,部分服务仅在特定区域可用,见 AWS Regional Services。
二、单操作代码示例(Single Actions)
单操作示例展示如何调用单个 DynamoDB 服务函数。这些函数全部封装在 src/scenario 模块下,入口定义见 src/scenario/mod.rs。示例清单如下:
| 操作 | 源码位置 | 底层 API |
|---|---|---|
| CreateTable(建表) | create.rs | create_table |
| PutItem(写入条目) | add.rs | put_item |
| DeleteItem(删除条目) | delete.rs | delete_item |
| DeleteTable(删表) | delete.rs | delete_table |
| ListTables(列表表) | list.rs | list_tables |
| Query(主键查询) | movies/server.rs | query |
| Scan(全表扫描) | list.rs | scan |
2.1 CreateTable:创建按需计费表
create.rs 中的create_table函数演示了如何创建一张"按需计费"(BillingMode::PayPerRequest)的表。该模式按实际请求量计费,无需预置容量,适合流量不稳定的场景。关键构建步骤:
AttributeDefinition:定义属性key的类型为字符串(ScalarAttributeType::S);KeySchemaElement:将该属性设置为分区键(KeyType::Hash);billing_mode(BillingMode::PayPerRequest):指定按需计费模式。
pub async fn create_table( client: &Client, table: &str, key: &str, ) -> Result<CreateTableOutput, Error> { let ad = AttributeDefinition::builder() .attribute_name(&a_name) .attribute_type(ScalarAttributeType::S) .build() .map_err(Error::BuildError)?; let ks = KeySchemaElement::builder() .attribute_name(&a_name) .key_type(KeyType::Hash) .build() .map_err(Error::BuildError)?; let create_table_response = client .create_table() .table_name(table_name) .key_schema(ks) .attribute_definitions(ad) .billing_mode(BillingMode::PayPerRequest) .send() .await; // ... }该函数内置了两组单元测试(create.rs#L56-L91):一组模拟 200 状态码断言建表成功,另一组模拟 400 状态码断言返回错误。测试使用仓库的sdk_examples_test_utils::single_shot_client!宏构造一次性客户端,无需真实 AWS 环境。
2.2 PutItem:写入条目
add.rs 中的add_item演示了通过put_item向表写入一条记录。示例中的条目包含username、account_type、age、first_name、last_name五个字段,其中username作为分区键。写入后从响应中取出attributes并回读各字段打印,形成"写后读"验证:
let user_av = AttributeValue::S(item.username); let type_av = AttributeValue::S(item.p_type); // ... let resp = client .put_item() .table_name(table) .item("username", user_av) .item("account_type", type_av) // ... .send() .await?;对应的单元测试(add.rs#L69-L114)模拟返回一条包含p_type、age、username、first_name、last_name的Attributes响应,并断言解析出的ItemOut结构完全一致——这也是理解 SDK 如何把 DynamoDB 的AttributeValue映射到 Rust 结构体的好范例。
2.3 DeleteItem 与 DeleteTable
delete.rs 同时包含两个操作:
delete_item(第 12 行):通过分区键名和值(AttributeValue::S)删除指定条目;delete_table(第 36 行):按表名删除整张表。
删除条目的测试(delete.rs#L55-L68)模拟 500 状态码验证错误路径的返回。
2.4 ListTables:列举表的四种姿势
list.rs 是本模块最丰富的一个文件,给出了列举表的四种典型实现:
list_tables(第 7 行):使用分页器(paginator)一次性收集全部表名:let paginator = client.list_tables().into_paginator().items().send(); let table_names = paginator.collect::<Result<Vec<_>, _>>().await?;list_tables_limit_10(第 43 行):单次请求用.limit(10)限制只返回 10 张表;list_tables_iterative(第 65 行):手动翻页循环——每次取 10 张,只要响应中的last_evaluated_table_name存在,就带上exclusive_start_table_name继续请求,直到取完为止;对应的测试(list.rs#L110-L147)用StaticReplayClient连续回放三页响应(a,b,c→d,e,f→g,h),验证翻页聚合结果为全部 8 张表;list_tables_are_more(第 150 行):只取前 10 张并借助last_evaluated_table_name.is_some()判断是否还有更多表。
2.5 Scan:扫描表内条目
list.rs 的list_items演示了scan操作:按指定page_size(默认 10)扫描表内条目,并通过into_paginator().items()自动聚合分页结果。
let page_size = page_size.unwrap_or(10); let items: Result<Vec<_>, _> = client .scan() .table_name(table) .limit(page_size) .into_paginator() .items() .send() .collect() .await;注意:
Scan会读取表中所有条目并消耗相应读容量,生产环境中应谨慎使用,优先考虑基于主键的Query。
2.6 Query:基于分区键的条件查询
movies/server.rs 中的movies_in_year演示了query操作:通过key_condition_expression指定查询条件,用表达式属性名(expression_attribute_names)和表达式属性值(expression_attribute_values)占位,查询指定年份的所有电影:
let results = client .query() .table_name(table_name) .key_condition_expression("#yr = :yyyy") .expression_attribute_names("#yr", "year") .expression_attribute_values(":yyyy", AttributeValue::N(year.to_string())) .send() .await?;返回的每个条目通过From<&HashMap<String, AttributeValue>>转换回Movie结构体(见 movies/mod.rs),完成了从 DynamoDBAttributeValue到 Rust 结构体的双向转换闭环。
三、完整场景示例(Scenarios)
除了单操作,本模块还提供两个完整的实战场景:连接本地 DynamoDB 实例,以及使用 PartiQL 完成全流程 CRUD。
3.1 场景一:连接本地 DynamoDB 实例
DynamoDB 提供本地可运行版本(DynamoDB Local),方便离线开发与测试。示例程序 src/bin/list-tables-local.rs 展示了如何覆盖 SDK 的 endpoint URL 与凭证,将客户端指向本地部署的 DynamoDB:
let config = aws_config::defaults(aws_config::BehaviorVersion::latest()) .test_credentials() // DynamoDB 本地版默认使用 8000 端口 .endpoint_url("http://localhost:8000") .load() .await; let dynamodb_local_config = aws_sdk_dynamodb::config::Builder::from(&config).build(); let client = aws_sdk_dynamodb::Client::from_conf(dynamodb_local_config);关键点:
test_credentials()提供本地测试用的哑凭证,因为本地实例不校验真实 AWS 凭证;endpoint_url("http://localhost:8000")将请求重定向到本地默认端口 8000;- 构造好客户端后,正常调用
client.list_tables().send().await即可列出本地实例中的全部表,并打印表名与总数。
这是理解"SDK 端点覆盖"机制的最小可运行示例,同样适用于其他需要指向本地/自建兼容服务的场景。
3.2 场景二:使用 PartiQL 查询与操作表
src/bin/partiql.rs 演示了通过 DynamoDB 的PartiQL(一种与 SQL 兼容的查询语言)直接使用execute_statementAPI 完成以下四类操作:
- SELECT:查询条目
- INSERT:新增条目
- UPDATE:更新条目
- DELETE:删除条目
程序运行流程如下(含命令行参数说明):
| 参数 | 含义 |
|---|---|
-i/--interactive | 交互模式,每步操作之间需按回车继续 |
-r/--region | 指定 AWS Region;未指定时读取AWS_REGION环境变量,仍未设置则默认us-west-2 |
-v/--verbose | 显示附加信息(SDK 版本、Region、表名/键名/键值、写入数据等) |
关键实现要点:
- 建表:
make_table用随机 10 位字符串作表名、随机 6 位字符串作分区键,同样采用按需计费模式(BillingMode::PayPerRequest); - INSERT:使用带占位符
?的 PartiQL 语句,并通过set_parameters传入AttributeValue列表:client.execute_statement() .statement(format!(r#"INSERT INTO "{}" VALUE {{ "{}": ?, "acount_type": ?, "age": ?, "first_name": ?, "last_name": ? }} "#, item.table, item.key)) .set_parameters(Some(vec![ AttributeValue::S(item.utype), AttributeValue::S(item.age), AttributeValue::S(item.first_name), AttributeValue::S(item.last_name), ])) .send().await - UPDATE:程序以"再次 INSERT 相同主键、改 age 为 44"的方式演示了条目更新(DynamoDB 中
PutItem对同主键是整体覆盖语义); - SELECT:
SELECT * FROM "表名" WHERE "键名" = ?,命中则打印条目,未命中则提示 "Did not find a match."; - DELETE:
DELETE FROM "表名" WHERE "键名" = ?; - 删表:
remove_table通过delete_table清理测试表; - 每次建表后调用
wait_for_ready_table(见 partiql.rs#L329-L345),每秒轮询一次describe_table,直到表状态不再是Creating才继续后续操作。
执行方式:
# 普通模式 cargo run --bin partiql # 交互模式(每步暂停) cargo run --bin partiql -- --interactive # 指定区域并开启详细输出 cargo run --bin partiql -- --region cn-north-1 --verbose四、运行示例与依赖配置
4.1 运行方式
rustv1 顶层文档(rustv1/README.md)规定了统一运行方式:每个示例用cargo run --bin [程序名]执行。本模块对应的二进制文件位于 src/bin 目录:
# 运行本地实例连接场景 cargo run --bin list-tables-local # 运行 PartiQL 场景 cargo run --bin partiql4.2 Cargo 依赖一览
Cargo.toml 定义了本模块的依赖,其中与 DynamoDB 直接相关的核心依赖包括:
| 依赖 | 版本 | 用途 |
|---|---|---|
aws-config | 1.0.1 | 加载凭证与 Region 配置(behavior-version-latest) |
aws-sdk-dynamodb | 1.3.0 | DynamoDB 客户端 |
serde_dynamo | 4 | AttributeValue与 serde 结构体互转(aws-sdk-dynamodb+0_22) |
axum | 0.5.16 | 电影查询场景的 HTTP 服务框架 |
clap | 4.4 | 命令行参数解析(derive特性) |
tokio | 1.20.1 | 异步运行时(full特性) |
sdk-examples-test-utils | 本地路径 | 测试工具(single_shot_client、test_event等) |
4.3 测试运行
本模块的测试分为两类(统一说明见 rustv1/README.md):
- 单元测试:不会访问真实 AWS、不会产生费用,直接运行:
cargo test例如 create.rs 与 add.rs 中的测试均通过
single_shot_client!宏模拟 HTTP 响应,无需真实环境即可验证逻辑; - 集成测试:可能对 AWS 账户产生变更或费用,通过
cargo test -- --ignored运行。
4.4 电影查询场景(Movies 模块)补充说明
若读者希望深入了解更完整的 DynamoDB 应用形态,可阅读 src/scenario/movies 模块——它构建了一个基于 axum 的 HTTP 服务:
- mod.rs 定义了
Movie/MovieInfo结构体、TABLE_NAME("movies")、错误类型以及Movie ↔ AttributeValue双向转换实现; - startup.rs 展示了初始化流程:检测表是否存在(
table_exists)→ 不存在则创建以year(数字型分区键)+title(字符串排序键)为复合主键的表 → 轮询describe_table等待表进入Active状态 → 从 moviedata.json 批量加载数据(每批 25 条WriteRequest,并循环重试未处理条目); - server.rs 提供 REST 接口
/与/:year,后者通过movies_in_year的 Query 操作返回该年份电影列表,并启用 CORS 支持浏览器跨域访问; - shutdown.rs 监听 Ctrl+C 与 SIGTERM 信号,在优雅退出时自动删除
movies表完成清理。
五、附加资源
- DynamoDB 开发者指南
- DynamoDB API 参考
- SDK for Rust DynamoDB 参考(docs.rs)
六、小结
本文从 rustv1/examples/dynamodb 出发,完整梳理了 AWS SDK for Rust 操作 DynamoDB 的七类单操作与两类实战场景:无论是通过list-tables-local覆盖 endpoint 对接本地实例,还是借助 PartiQL 以类 SQL 语句完成 CRUD,均可在仓库源码中找到可直接运行的实现与配套单元测试。对想要快速搭建 DynamoDB 数据访问层的 Rust 开发者而言,这些示例既是入门教材,也是可复用的代码资产。
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
- 示例工程
- 教程
- 后端
【免费下载链接】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 SDK for Ruby 操作 DynamoDB 完整实战指南:从建表、增删改查到 PartiQL
AWS SDK for Ruby 操作 DynamoDB 完整实战指南:从建表、增删改查到 PartiQL 本指南以 aws doc sdk examples
示例工程教程后端使用 AWS SDK for Go 操作 Amazon DynamoDB:建表、增删改查与批量加载实战指南
使用 AWS SDK for Go 操作 Amazon DynamoDB:建表、增删改查与批量加载实战指南 本指南以仓库中 go/dynamodb/README
示例工程教程后端使用 AWS SDK for PHP 操作 Amazon DynamoDB:从建表演示到 PartiQL 批量查询的完整示例指南
使用 AWS SDK for PHP 操作 Amazon DynamoDB:从建表演示到 PartiQL 批量查询的完整示例指南 本文以 aws doc sdk
示例工程教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考