Scrittura condizionale DynamoDB con la AWS CLI
Una scrittura condizionale è semplice da inviare dalla shell e scomoda da leggere, perché il risultato interessante di una fallita arriva come errore invece che come output. Le espressioni di condizione DynamoDB coprono ciò che l'espressione può dire; questa pagina riguarda l'eseguirne una dalla CLI e recuperare l'Item perdente dal fallimento.
Codice
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"}}'In caso di successo il comando non stampa nulla ed esce con 0. Se un altro writer è arrivato prima, la condizione fallisce e la CLI riporta il messaggio del servizio:
An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failedSpiegazione
- Il successo è silenzioso. Nessun output, uscita 0. Non c'è nulla da parsare e nulla su cui asserire, quindi uno script di shell deve trattare lo stato di uscita come il risultato. Aggiungi
--return-values ALL_NEWse vuoi che l'Item aggiornato venga stampato. - Il fallimento è lo stato di uscita 254, che è il codice della CLI v2 per un errore lato client ed è condiviso con una richiesta malformata. Ramifica sul messaggio prima di riprovare, altrimenti un refuso nella tua espressione diventa un loop di backoff infinito.
--return-values-on-condition-check-failure ALL_OLDqui funziona. I valori validi sonoALL_OLDeNONE, e non consuma capacità di lettura. Estrarre l'Item dall'errore richiede un flag in più, trattato qui sotto.- La condizione e l'aggiornamento sono flag separati con uno spazio dei nomi condiviso.
--expression-attribute-namese--expression-attribute-valuesvengono uniti tra--update-expressione--condition-expression, ed è per questo che i nomi generati vanno#upd0,#cond0invece di ripartire da capo per ogni clausola. Riusa un placeholder per due significati diversi e il secondo vince silenziosamente. - Una scrittura fallita viene comunque fatturata. La Developer Guide è esplicita: una condizione che valuta a falso consuma capacità di scrittura lo stesso, dimensionata sul maggiore tra il vecchio e il nuovo Item. Le condizioni non sono una sonda di esistenza a basso costo.
L'output di fallimento, e come estrarne l'Item
Esegui il blocco una volta e riesce silenziosamente. Eseguilo una seconda volta, quando Version non è più 7, e aws-cli/2.36.9 stampa su stderr:
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failedAggiungi --return-values-on-condition-check-failure ALL_OLD e l'output predefinito ti dice che c'è dell'altro, senza mostrartelo:
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> è l'Item, trattenuto dal renderer di testo predefinito. Aggiungi --cli-error-format json e viene stampato tutto:
{
"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"}
}
}(Le mappe di attributi sono state ripiegate su una riga ciascuna; tutto il resto è come stampato.) Version è 8 e Genre è impostato perché la prima esecuzione è riuscita. Questo è il loop di optimistic locking chiuso da uno script di shell: convoglia stderr in jq -r '.Item.Version.N', rimettilo come :expectedVersion, riprova. Nessun get-item, e nessuna finestra tra la lettura e il retry in cui un terzo writer possa infilarsi.
I retry non sono gratuiti. Ogni tentativo respinto consuma un'unità di scrittura, quindi una chiave contesa sotto un loop stretto fattura costantemente senza fare progressi. Il calcolatore dei prezzi trasforma un tasso di scrittura in una cifra mensile se vuoi sapere quanto costa davvero una tempesta di retry prima di limitare i tentativi.
Per eseguire queste guardie sulle tue tabelle senza dover fare l'escaping shell delle mappe di placeholder, scarica DynoTable.
Esempi correlati
- Scrittura condizionale DynamoDB in Node.js — lo stesso optimistic lock con AWS SDK v3.
- Scrittura condizionale DynamoDB in Python — lo stesso optimistic lock con boto3.
- DynamoDB PutItem con la AWS CLI — il put di sola creazione con
attribute_not_exists. - Espressioni di condizione DynamoDB — ogni funzione, con i pattern.
- Capire ReturnValues — cosa ti dà ciascuna opzione di ritorno.
- DynamoDB ConditionalCheckFailedException — quando il check fallito è previsto, e come gestirlo a basso costo.
Riferimenti
- 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
Ultima verifica 2026-07-28 rispetto alla documentazione ufficiale AWS collegata sopra.