用 AWS CLI 做 DynamoDB Scan

aws dynamodb scan 会自动分页,这很方便,但也意味着你用来判断损失有多大的那个唯一数字,默认就是错的。什么时候该彻底避开这个操作,见 Query vs. Scan

代码

aws dynamodb scan \
  --table-name 'Music' \
  --filter-expression '#filter0 >= :filterValue0' \
  --expression-attribute-names '{"#filter0":"Year"}' \
  --expression-attribute-values '{":filterValue0":{"N":"2010"}}'

--return-consumed-capacity 报告的是一页,不是整次扫描

数据集是 600 首歌,每首大约 3.9 KB,其中 8 首匹配。给上面那条命令加上 --return-consumed-capacity TOTAL,CLI 打印的是:

{ "Count": 8, "ScannedCount": 600, "CU": 128.5 }

这次扫描真实花掉的是跨三页的 284.5 个读取单元。CountScannedCount 是三页累加的;ConsumedCapacity 却只取了第一页,其余的被丢掉了。与其说这是 bug,不如说这是一条声明好的规则——botocore 的 DynamoDB 分页器配置把 CountScannedCount 列为结果键,把 ConsumedCapacity 列为非聚合键。

破绽在于:工作量没变,这个数字却会变。同一张表、同样读了 600 个项目,只多加一个参数:

--page-size 50  ->  { "Count": 8, "ScannedCount": 600, "CU": 24.0 }

如果你要根据一次 CLI 扫描来给表定容量,请用 --page-size--starting-token 自己把各页累加,或者从 CloudWatch 读取容量。

--max-items 并不会让扫描停下来

--max-items 3 读起来像是一次廉价的抽样。其实不是:

--max-items 3  ->  { "Count": 8, "ScannedCount": 600 }

CLI 会一直请求下一页,直到攒够足够的匹配项——在一个高选择性的过滤器下,这意味着整张表——然后再截断打印出来的列表。它自己的续读 token 把这一点说得明明白白:

{"ExclusiveStartKey": {"Artist": {"S": "Arturo Sandoval"},
 "SongTitle": {"S": "Cubano Chant 0541"}}, "boto_truncate_amount": 3}

boto_truncate_amount 是一个客户端计数器。要限制 DynamoDB 读多少,请用 --page-size,它会给每个底层请求设上 API 的 Limit,再用 --starting-token 续读:

aws dynamodb scan \
  --table-name 'Music' \
  --page-size 500 \
  --max-items 100 \
  --starting-token "$NEXT_TOKEN"

2026-07-28 用 aws-cli/2.36.9 针对 DynamoDB Local(amazon/dynamodb-local)实测。上方的 JSON 是 CLI 自己的输出,只是用 --query 重新排布以适应宽度。

说明

  • --filter-expression 是在读取之后才跑的,所以它缩小的是输出,不是账单。#filter0 通过 --expression-attribute-names 指代 Year,因为 Year 是保留字。
  • --expression-attribute-values 要求这个数字被引两次:JSON 外面一层 shell 引号,值本身再作为 JSON 字符串。去掉里面那层引号根本到不了 DynamoDB——CLI 会在本地就拒绝它,报 Invalid type for parameter ExpressionAttributeValues.:v.N, value: 2010, type: <class 'int'>, valid types: <class 'str'>
  • --page-size 才是会改变 API 调用的那个参数。它会变成每个底层请求上的 Limit,限制每页求值的项目数。分页家族的其余成员(--max-items--starting-token)都只是 CLI 在管理自己的输出。
  • 并行扫描需要给每个 worker 加 --segment N --total-segments M,而且每个 worker 各自维护自己的 --starting-token。它买到的是墙上时钟时间,不是容量。

用可视化的方式来做

DynamoDB 表达式构建器会输出已经为 shell 转义好的过滤器和两个 JSON 映射,从而去掉那层让 CLI 表达式还没到 DynamoDB 就先失败的引号问题。

要在图形界面里浏览表、用带过滤和分页的网格,请下载 DynoTable,而不是从终端里盲扫。

相关指南

参考资料

可视化构建此请求

在免费的 DynamoDB 查询构建器中组装此操作 —— 键条件、筛选、索引、Limit、排序方向和分页循环 —— 再把它作为可运行的 SDK v3、CLI 或 boto3 程序复制回来。

打开 DynamoDB 查询构建器

无需控制台即可使用 DynamoDB

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

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