使用 AWS CLI 的 DynamoDB 条件写入

条件写入会给 put-itemupdate-itemdelete-item 附加一个 --condition-expression:DynamoDB 会针对当前项目对它求值,仅在成立时才应用该写入——原子地进行,没有读-改-写竞态。这是 DynamoDB 的乐观锁原语。本示例用一次版本检查来保护一次更新。

Code

aws dynamodb update-item \
  --table-name 'Music' \
  --key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
  --update-expression 'SET #upd0 = :updValue0, #version = :newVersion' \
  --condition-expression 'attribute_exists(#cond0) AND #version = :expectedVersion' \
  --expression-attribute-names '{"#upd0":"Genre","#version":"Version","#cond0":"Artist"}' \
  --expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":expectedVersion":{"N":"7"},":newVersion":{"N":"8"}}'

成功时该命令不打印任何内容,并以 0 退出。如果另一个写入者抢先一步,条件就会失败:

An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failed

说明

  • --condition-expression — 与写入原子地一起针对已存储项目进行检查。可用函数:attribute_existsattribute_not_existsattribute_typecontainsbegins_withsize,外加比较符(=<><><=>=BETWEENIN)以及 AND/OR/NOT
  • 两个主力惯用法:
    • 更新上使用 attribute_exists(#key) = "仅更新,绝不创建"。没有它,对缺失键的 update-item 会静默地创建该项目(意外的 upsert bug)。
    • put上使用 attribute_not_exists(#key) = "仅创建,绝不覆盖"——见 PutItem 页面
  • 乐观锁 — 读取项目(版本 7),然后在把版本提升到 8 的同时以 #version = :expectedVersion 写入。两个并发写入者不可能同时获胜;失败者会以非零退出并抛出 ConditionalCheckFailedException,随后重新读取并基于新版本重试。
  • --return-values-on-condition-check-failure ALL_OLD — 请求 DynamoDB 在失败时附带当前项目(有效值为 ALL_OLD | NONE;不消耗读取容量)。SDK 会在异常上暴露该项目;而 CLI 的默认错误输出只打印消息,因此脚本通常在失败后用 get-item 重新读取。
  • 失败的条件写入仍会对该次写入尝试计费——不要把条件当作免费的存在性探测。

可视化操作

条件表达式正是 DynamoDB Expression Builder 所构建的——选择函数,即可获得表达式外加名称/值映射,作为一条可直接运行的 CLI 命令。

想用生成的、可审阅的表达式来编辑项目,而不是 shell 引号里的占位符——请下载 DynoTable

相关示例

References

Last verified 2026-07-13 against the official AWS documentation linked above.

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。