用 AWS CLI 做 DynamoDB UpdateItem

五个参数,其中三个是 DynamoDB JSON,而且个个都在跟你的 shell 较劲:让 aws dynamodb update-item 变麻烦的是这些,不是更新本身。CLI 在其他所有客户端之上多加的,是请求可能被拒绝的第二个地方,以及一组精确到能告诉你是哪一处出问题的退出码。

代码

aws dynamodb update-item \
  --table-name 'Music' \
  --key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
  --update-expression 'SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2' \
  --expression-attribute-names '{"#upd0":"Genre","#upd1":"Year","#upd2":"Awards"}' \
  --expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":updValue1":{"N":"1994"},":updValue2":{"N":"1"}}' \
  --return-values ALL_NEW

对一个原本既没有 Genre 也没有 Awards 的项运行,这条命令打印出:

{
    "Attributes": {
        "Artist": {
            "S": "Arturo Sandoval"
        },
        "Awards": {
            "N": "1"
        },
        "Genre": {
            "S": "Latin Jazz"
        },
        "Year": {
            "N": "1994"
        },
        "SongTitle": {
            "S": "Cubano Chant"
        }
    }
}

ADD 作用在一个不存在的 Awards 上时从零开始,而属性是按服务端的顺序回来的,不是表达式写它们的顺序。别把这个管道给任何依赖位置的东西。

说明

  • --key——完整主键,用 DynamoDB JSON 表示。对一张复合键的表只传分区键,你得到的是 ValidationException: The number of conditions on the keys is invalid,而不是一次部分匹配。

  • --update-expression——SETADDREMOVEDELETE 子句,通过 --expression-attribute-names 做别名。这里的 ADD #upd2 :updValue2 是对 Awards 的一次原子自增;完整的子句语法在更新表达式里。

  • 数字是带引号的字符串,而且 CLI 会赶在 DynamoDB 之前检查这一点。写成 {"N":1994} 而不是 {"N":"1994"},那就什么都不会离开你的机器:

    aws: [ERROR]: An error occurred (ParamValidation): Parameter validation failed:
    Invalid type for parameter ExpressionAttributeValues.:y.N, value: 1994, type: <class 'int'>, valid types: <class 'str'>
  • 退出码会告诉你是哪一半失败了。那次客户端拒绝的退出码是 252。一个 DynamoDB 真的应答过并拒绝了的请求,退出码是 254

    aws: [ERROR]: An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: Year

    252 永远是你 JSON 里的 bug。254 可能是你刻意预期会失败的一个条件,所以脚本应当在这两者之间分支,而不是在"非零"上分支。

  • 不加 --return-values 时命令什么都不打印,退出码 0。没有一行"已更新 1 个项"可以 grep,所以沉默即成功。UPDATED_NEW 只返回表达式碰过的那些属性,当你只需要新的计数器值时,它是便宜的选项。

  • 先加一层引号,然后改用文件。给每个 JSON 参数加单引号,好让 shell 别碰 "$;任何很长的内容都挪进 --expression-attribute-values file://values.json,而不是把它转义两遍。

  • upsert 语义——键不存在时 update-item 会创建这个项,上面的 Awards 就是这么冒出来的。加上 --condition-expression "attribute_exists(Artist)" 可以让它只做更新。

这里没有任何东西会替你构建表达式

本站记录的五个客户端里,恰好只有一个会生成 UpdateExpressionGo SDK 的 expression。Node、Python 和 Java 都是把字符串丢给你自己写。CLI 是这四者里最糟的一种,因为你还要在一个想解释同样这些字符的 shell 里,亲手写两个别名映射和那些 DynamoDB JSON。

DynamoDB 表达式构建器填的正是这个缺口:在浏览器里把子句拼好,复制一条已经加好引号的 aws dynamodb update-item 命令。要在真实的表上做同样的修改、而且一个引号都不用转义,请下载 DynoTable

相关指南

参考资料

最后核实于 2026-07-28,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。