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 failed

Spiegazione

  • 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_NEW se 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_OLD qui funziona. I valori validi sono ALL_OLD e NONE, 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-names e --expression-attribute-values vengono uniti tra --update-expression e --condition-expression, ed è per questo che i nomi generati vanno #upd0, #cond0 invece 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 failed

Aggiungi --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

Riferimenti

Ultima verifica 2026-07-28 rispetto alla documentazione ufficiale AWS collegata sopra.

Lavora con DynamoDB senza la Console

Un client desktop veloce per DynamoDB che esegue il vero SQL che DynamoDB non può — JOINs, GROUP BY, aggregazioni — con modifica visuale e un agente AI sulle tue chiavi Bedrock.

Prova gratuita di 30 giorni, senza carta di credito — poi il piano Free senza limiti di tempo.