Écriture conditionnelle DynamoDB avec l'AWS CLI
Une écriture conditionnelle est simple à envoyer depuis le shell et pénible à lire, parce que le résultat intéressant — celui d'un échec — arrive sous forme d'erreur plutôt que de sortie. Les expressions de condition DynamoDB couvrent ce que l'expression peut dire ; cette page porte sur son exécution depuis la CLI et sur la récupération de l'élément perdant à partir de l'échec.
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"}}'En cas de succès, la commande n'affiche rien et sort avec le code 0. Si un autre écrivain est arrivé le premier, la condition échoue et la CLI rapporte le message du service :
An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failedExplication
- Le succès est silencieux. Aucune sortie, code de sortie 0. Il n'y a rien à analyser et rien sur quoi s'appuyer, donc un script shell doit traiter le code de sortie comme le résultat. Ajoute
--return-values ALL_NEWsi tu veux que l'élément mis à jour s'affiche. - L'échec, c'est le code de sortie 254, celui que la CLI v2 réserve à une erreur côté client et qu'il partage avec une requête malformée. Branche sur le message avant de réessayer, sinon une faute de frappe dans ton expression devient une boucle de backoff infinie.
--return-values-on-condition-check-failure ALL_OLDfonctionne bel et bien ici. Les valeurs valides sontALL_OLDetNONE, et il ne consomme aucune capacité de lecture. Extraire l'élément de l'erreur demande un flag de plus, détaillé ci-dessous.- La condition et la mise à jour sont des flags distincts qui partagent un espace de noms.
--expression-attribute-nameset--expression-attribute-valuessont fusionnés entre--update-expressionet--condition-expression, ce qui explique pourquoi les noms générés s'enchaînent#upd0,#cond0au lieu de repartir de zéro à chaque clause. Réutilise un placeholder pour deux sens différents et le second l'emporte silencieusement. - Une écriture en échec est quand même facturée. Le Developer Guide est explicite : une condition qui s'évalue à faux consomme quand même de la capacité d'écriture, dimensionnée sur le plus gros de l'ancien et du nouvel élément. Les conditions ne sont pas un test d'existence bon marché.
La sortie d'erreur, et comment en extraire l'élément
Lance le bloc une fois et il réussit en silence. Lance-le une deuxième fois, quand Version ne vaut plus 7, et aws-cli/2.36.9 affiche sur stderr :
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failedAjoute --return-values-on-condition-check-failure ALL_OLD et la sortie par défaut t'annonce qu'il y a plus, sans le montrer :
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed
Additional error details:
Item: <complex value>
Use "--cli-error-format json" or another error format to see the full details.<complex value>, c'est l'élément, retenu par le formateur texte par défaut. Ajoute --cli-error-format json et le tout s'affiche :
{
"Message": "The conditional request failed",
"Code": "ConditionalCheckFailedException",
"Item": {
"Artist": {"S": "Arturo Sandoval"},
"Year": {"N": "1994"},
"Version": {"N": "8"},
"SongTitle": {"S": "Cubano Chant"},
"AlbumTitle": {"S": "Danzon"},
"Genre": {"S": "Latin Jazz"}
}
}(Les maps d'attributs ont été repliées sur une ligne chacune ; tout le reste est tel qu'affiché.) Version vaut 8 et Genre est renseigné parce que la première exécution a réussi. Voilà la boucle de verrouillage optimiste bouclée depuis un script shell : passe stderr dans jq -r '.Item.Version.N', réinjecte la valeur comme :expectedVersion, réessaie. Pas de get-item, et aucune fenêtre entre la lecture et la reprise où un troisième écrivain pourrait se glisser.
Les reprises ne sont pas gratuites. Chaque tentative rejetée consomme une unité d'écriture : une clé disputée sous une boucle serrée facture sans relâche sans jamais avancer. Le calculateur de tarifs traduit un débit d'écriture en montant mensuel si tu veux savoir ce que coûte réellement une tempête de reprises avant de plafonner les tentatives.
Pour exécuter ces gardes sur tes propres tables sans échapper les maps de placeholders dans le shell, télécharge DynoTable.
Exemples liés
- Écriture conditionnelle DynamoDB en Node.js — le même verrou optimiste avec AWS SDK v3.
- Écriture conditionnelle DynamoDB en Python — le même verrou optimiste avec boto3.
- DynamoDB PutItem avec l'AWS CLI — le put
attribute_not_existsen création seule. - Les expressions de condition DynamoDB — chaque fonction, avec des motifs.
- Comprendre ReturnValues — ce que chaque option de retour te donne.
- DynamoDB ConditionalCheckFailedException — quand la vérification échouée est attendue, et comment la gérer à moindre coût.
Références
- UpdateItem — Amazon DynamoDB API Reference
- update-item — AWS CLI Command Reference
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Dernière vérification le 2026-07-28 par rapport à la documentation officielle AWS liée ci-dessus.