用 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——SET、ADD、REMOVE和DELETE子句,通过--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: Year252 永远是你 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)"可以让它只做更新。
这里没有任何东西会替你构建表达式
本站记录的五个客户端里,恰好只有一个会生成 UpdateExpression:Go SDK 的 expression 包。Node、Python 和 Java 都是把字符串丢给你自己写。CLI 是这四者里最糟的一种,因为你还要在一个想解释同样这些字符的 shell 里,亲手写两个别名映射和那些 DynamoDB JSON。
DynamoDB 表达式构建器填的正是这个缺口:在浏览器里把子句拼好,复制一条已经加好引号的 aws dynamodb update-item 命令。要在真实的表上做同样的修改、而且一个引号都不用转义,请下载 DynoTable。
相关指南
- DynamoDB 更新表达式——
SET、ADD、REMOVE、DELETE,以及常用写法。 - 理解 ReturnValues——每个
--return-values选项分别给你什么。 - "Attribute name is a reserved keyword"——为什么这里的别名映射不是可选的。
- "Invalid UpdateExpression" 语法错误——常见的 SET/ADD 语法错误,逐一解读。
参考资料
- UpdateItem — Amazon DynamoDB API Reference
- update-item — AWS CLI Command Reference
- Update expressions — Amazon DynamoDB Developer Guide
最后核实于 2026-07-28,依据上方链接的 AWS 官方文档。