news 2026/9/29 7:00:37

使用 AWS SDK for Rust 操作 Amazon DynamoDB:从增删改查到本地实例与 PartiQL 完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 AWS SDK for Rust 操作 Amazon DynamoDB:从增删改查到本地实例与 PartiQL 完整实战
  • 示例工程
  • 教程
  • 后端

【免费下载链接】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.

项目地址:https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
点击查看免费下载

导读

本文基于当前仓库中的 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 ⚠ 重要注意事项

运行本模块代码前务必了解以下三点(均来自原文档,仓库中亦有对应体现):

  1. 可能产生费用:运行这些代码可能导致您的 AWS 账户产生费用,详情参考 AWS Pricing 与 Free Tier;
  2. 运行测试同样可能产生费用:尤其涉及真实 AWS 资源的集成测试;
  3. 遵循最小权限原则:建议为代码授予最小权限(Least Privilege),仅提供完成任务所需的最低权限,详见 Grant least privilege;
  4. 区域可用性:这些代码未经所有 AWS 区域测试,部分服务仅在特定区域可用,见 AWS Regional Services。

二、单操作代码示例(Single Actions)

单操作示例展示如何调用单个 DynamoDB 服务函数。这些函数全部封装在 src/scenario 模块下,入口定义见 src/scenario/mod.rs。示例清单如下:

操作源码位置底层 API
CreateTable(建表)create.rscreate_table
PutItem(写入条目)add.rsput_item
DeleteItem(删除条目)delete.rsdelete_item
DeleteTable(删表)delete.rsdelete_table
ListTables(列表表)list.rslist_tables
Query(主键查询)movies/server.rsquery
Scan(全表扫描)list.rsscan

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 是本模块最丰富的一个文件,给出了列举表的四种典型实现:

  1. list_tables(第 7 行):使用分页器(paginator)一次性收集全部表名:
    let paginator = client.list_tables().into_paginator().items().send(); let table_names = paginator.collect::<Result<Vec<_>, _>>().await?;
  2. list_tables_limit_10(第 43 行):单次请求用.limit(10)限制只返回 10 张表;
  3. 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 张表;
  4. 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 partiql

4.2 Cargo 依赖一览

Cargo.toml 定义了本模块的依赖,其中与 DynamoDB 直接相关的核心依赖包括:

依赖版本用途
aws-config1.0.1加载凭证与 Region 配置(behavior-version-latest)
aws-sdk-dynamodb1.3.0DynamoDB 客户端
serde_dynamo4AttributeValue与 serde 结构体互转(aws-sdk-dynamodb+0_22)
axum0.5.16电影查询场景的 HTTP 服务框架
clap4.4命令行参数解析(derive特性)
tokio1.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.

项目地址:https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
点击查看免费下载
上一篇:Windows电脑变身AirPlay接收器:Shairport4w完全指南
下一篇:如何轻松实现高效百度网盘链接解析:开源工具的完整实用指南

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 6:59:24

hindsight:用RAG和大模型回顾情绪日记,实现情绪后见之明

我最早看到 hindsight 这个项目的时候&#xff0c;愣了一下——它的定位很怪&#xff0c;不是帮你怎么控制情绪&#xff0c;而是帮你怎么回顾情绪。按英文直译&#xff0c;hindsight 就是“后见之明”&#xff0c;项目想做的事其实特别朴素&#xff1a;把你散落在各处的日常情绪…

作者头像 李华
网站建设 2026/9/29 6:56:58

TensorFlow工程实战:安装避坑、机制解析与生产部署要点

1. 先别急着站队&#xff1a;TensorFlow与PyTorch背后的生态博弈最近接手一个项目&#xff0c;客户的算法原型是用PyTorch训练的&#xff0c;生产部署却明确要求TensorFlow。迁移过程中&#xff0c;我把TensorFlow的安装、数据管线、模型训练、导出整条链路重新走了一遍&#x…

作者头像 李华
网站建设 2026/9/29 6:56:06

串口到网络通讯转换:TCP/IP网关、透明传输与现场排错

手头攒着一台跑了十来年的老设备&#xff0c;面板上只有一路DB9串口&#xff0c;协议手册还是影印版&#xff1b;另一头是后台服务器&#xff0c;天天催着要实时数据。这种局面下&#xff0c;基于TCP/IP实现串口到网络的通讯转换&#xff0c;基本是绕不过去的一道工序。所谓串口…

作者头像 李华
网站建设 2026/9/29 6:55:33

局域网安全毕业设计论文方案:VLAN划分与防火墙部署详解

简介&#xff1a;一份面向计算机与信息安全专业毕业生的网络安全设计毕业设计论文文档&#xff0c;以局域网安全控制与病毒防治为主线&#xff0c;系统梳理了从安全现状、威胁分析到防护实施的完整路径。内容涵盖网络分段、以交换式集线器代替共享式集线器、VLAN划分等局域网安…

作者头像 李华