Query DynamoDB avec l'AWS CLI
aws dynamodb query lit une partition, éventuellement restreinte par la clé de tri (Query vs Scan explique quand c'est le bon choix, et les expressions de condition de clé listent chaque opérateur autorisé). Ce que la CLI ajoute par-dessus, c'est sa propre couche de pagination — la source de la plupart des surprises sur cette commande.
Code
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)' \
--expression-attribute-names '{"#hashKey":"Artist","#rangeKey":"SongTitle"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"},":rangeKeyValue":{"S":"C"}}'Les alias #hashKey/#rangeKey résolvent vers Artist/SongTitle via --expression-attribute-names, ce qui empêche un mot réservé de casser la commande. Ajoute --no-scan-index-forward pour un ordre décroissant de clé de tri ; l'ordre croissant est la valeur par défaut.
Pagination
Par défaut, la CLI pagine automatiquement — elle suit LastEvaluatedKey en interne et affiche le résultat combiné. Pour paginer manuellement (par exemple sur de gros jeux de résultats), contrôle-la avec :
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue' \
--expression-attribute-names '{"#hashKey":"Artist"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"}}' \
--page-size 100 \
--max-items 50
# The output includes a "NextToken"; pass it back with --starting-token to continue.Explication
La CLI cache la pagination, y compris au chiffre de coût. Après avoir peuplé une partition de 30 éléments d'environ 60 Ko chacun, soit à peu près 1,8 Mo et donc deux pages de service, la même requête a été lancée de trois façons avec --return-consumed-capacity TOTAL :
default (auto-paginate) Count: 30 CapacityUnits: 132.0 LastEvaluatedKey: null
--no-paginate Count: 18 CapacityUnits: 132.0 LastEvaluatedKey: {…S017}
--max-items 3 Count: 18 items printed: 3 NextToken: eyJFeGNsdXNpdmVTdGFydEtleSI6…La pagination manuelle a révélé le coût réel : la page 1 faisait 18 éléments à 132,0 unités, la page 2 en faisait 12 à 88,0 — la requête a donc réellement consommé 220,0 unités de lecture. L'exécution auto-paginée a fait les deux appels, renvoyé les 30 éléments, et déclaré 132,0. La CLI fusionne Items et Count entre les pages, mais pas ConsumedCapacity : le nombre affiché sous-estime donc cette requête de 40 %. Si tu dimensionnes ta capacité à partir de la sortie de la CLI, pagine à la main ou tu dimensionneras pour une seule page.
--max-items est une limite d'affichage. Ce n'est pas un Limit. La troisième exécution ci-dessus a affiché trois éléments et déclaré malgré tout Count: 18 et ScannedCount: 18, parce que la page de service qu'elle a tronquée faisait 18 éléments et environ 1 Mo. Tu as tout payé. Le paramètre DynamoDB qui borne réellement la lecture s'appelle Limit, et la CLI l'expose sous le nom --page-size.
Les deux flags font donc des métiers sans rapport. --page-size devient le Limit de l'API et change ce que chaque appel de service lit ; --max-items décide seulement quelle part du résultat fusionné atteint ton terminal, et émet un NextToken pour le reste. Ce token est un blob base64 de la comptabilité interne de la CLI, pas le LastEvaluatedKey de DynamoDB, et il revient par --starting-token.
Il n'existe ni --limit ni --exclusive-start-key. Regarde aws dynamodb query help sur 2.36.9 : ni l'un ni l'autre n'apparaît dans le synopsis. La CLI supprime les deux paramètres de pagination de DynamoDB et y substitue les trois siens. La boucle naturelle — prendre LastEvaluatedKey d'un appel et l'injecter dans le suivant — n'a donc aucun flag où l'injecter. Le chemin de retour vers l'API brute est --cli-input-json, qui prend la requête telle quelle :
--cli-input-json with "Limit": 5 and an "ExclusiveStartKey"
→ Count: 5 CapacityUnits: 37.0 LastEvaluatedKey: {"Artist":…,"SongTitle":"S007"}Note que cela a aussi désactivé le paginateur : l'exécution a renvoyé une seule page et un vrai LastEvaluatedKey même sans --no-paginate. Si tu écris une boucle shell sur une grosse partition, --cli-input-json est la forme honnête, et --no-paginate la forme rapide.
--query s'exécute une fois l'argent dépensé. Le flag global --query est du JMESPath appliqué à la réponse dans ton shell. Une expression JMESPath comme Items[?Year > '2010'] ressemble à un filtre sans en être un : chaque élément a été lu, transféré et facturé avant que JMESPath ne le voie. --filter-expression évite au moins le transfert des données, mais AWS est explicite : il "is applied after the items have already been read; the process of filtering does not consume any additional read capacity units" (récupéré le 2026-07-28). Cela coupe dans les deux sens, puisque cela signifie que le filtre ne les réduit pas non plus. Le seul moyen de lire moins est une condition de clé plus étroite ou un index.
Une page fait 1 Mo, quoi que tu aies demandé. "A single Query operation will read up to the maximum number of items set (if using the Limit parameter) or a maximum of 1 MB of data" (récupéré le 2026-07-28). Une partition plus large que ça pagine toujours, et c'est pourquoi la requête de 30 éléments ci-dessus n'a jamais tenu en un seul appel.
Interroger un index demande un flag de plus. --index-name bascule la condition de clé sur les clés de cet index ; un index secondaire global refuse en plus --consistent-read. Voir Query sur un GSI avec l'AWS CLI.
Le faire visuellement
Réussir du premier coup la condition de clé, les deux maps de placeholders et la boucle de pagination dans une seule commande, c'est toute la difficulté ici. Le DynamoDB Query Builder gratuit compose la requête, index et pagination compris, et l'émet sous forme de commande CLI exécutable.
Pour lancer des requêtes sur tes propres tables — formulaire de condition de clé, grille qui pagine au défilement, copie de la requête sous forme de commande CLI — télécharge DynoTable.
Guides liés
- Query vs. Scan — pourquoi
queryest le bon choix par défaut. - Pagination —
LastEvaluatedKey,ExclusiveStartKey, et pourquoiLimitn'est pas une taille de page. - "Query condition missed key schema element" — la condition de clé nomme le mauvais attribut ou saute la clé de partition.
- "Query key condition not supported" — un opérateur inutilisable dans une condition de clé, comme contains ou une seconde condition de clé de tri.
Références
- Query — Amazon DynamoDB API Reference
- query — AWS CLI Command Reference
- Using the pagination options in the AWS CLI — AWS CLI User Guide
- Filtering AWS CLI output — AWS CLI User Guide
- Querying tables — Amazon DynamoDB Developer Guide
Mesuré le 2026-07-28 avec aws-cli/2.36.9 sur DynamoDB Local (amazon/dynamodb-local) sur le port 9000, sur une partition de 30 éléments d'environ 60 Ko chacun. Les comptes, tokens et mesures de capacité ci-dessus sont la sortie capturée. DynamoDB Local calcule la capacité avec les règles d'arrondi documentées ; considère les chiffres absolus comme une démonstration de la forme, et mesure tes propres tables sur le service avant de dimensionner.