Scrittura condizionale DynamoDB in Python (boto3)

Una scrittura condizionale collega una ConditionExpression a put_item, update_item o delete_item: DynamoDB la valuta rispetto all'Item corrente e applica la scrittura solo se è vera — in modo atomico, senza race di lettura-modifica-scrittura. È la primitiva di locking ottimistico di DynamoDB. Questo esempio protegge un aggiornamento con un controllo di versione.

Code

import boto3

client = boto3.client("dynamodb")

# Update the item only if nobody changed it since we read version 7.
try:
    client.update_item(
        TableName="Music",
        Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
        UpdateExpression="SET #upd0 = :updValue0, #version = :newVersion",
        ConditionExpression="attribute_exists(#cond0) AND #version = :expectedVersion",
        ExpressionAttributeNames={"#upd0": "Genre", "#version": "Version", "#cond0": "Artist"},
        ExpressionAttributeValues={
            ":updValue0": {"S": "Latin Jazz"},
            ":expectedVersion": {"N": "7"},
            ":newVersion": {"N": "8"},
        },
        ReturnValuesOnConditionCheckFailure="ALL_OLD",
    )
    print("Updated to version 8")
except client.exceptions.ConditionalCheckFailedException as e:
    # With ReturnValuesOnConditionCheckFailure="ALL_OLD", the current item
    # rides back on the exception — no extra read to see what beat you.
    print("Lost the race — item is now:", e.response.get("Item"))

Spiegazione

  • ConditionExpression — verificata rispetto all'Item memorizzato in modo atomico con la scrittura. Funzioni disponibili: attribute_exists, attribute_not_exists, attribute_type, contains, begins_with, size, più i comparatori (=, <>, <, >, <=, >=, BETWEEN, IN) e AND/OR/NOT.
  • I due idiomi principali:
    • attribute_exists(#key) su un update = "solo aggiornamento, mai creazione". Senza di essa, update_item su una chiave mancante crea silenziosamente l'Item (il bug dell'upsert accidentale).
    • attribute_not_exists(#key) su un put = "solo creazione, mai sovrascrittura" — mostrato nella pagina PutItem.
  • Locking ottimistico — leggi l'Item (versione 7), poi scrivi con #version = :expectedVersion incrementando a 8. Due writer concorrenti non possono vincere entrambi; il perdente ottiene ConditionalCheckFailedException, rilegge e riprova sulla nuova versione.
  • ReturnValuesOnConditionCheckFailure="ALL_OLD" — mette l'Item corrente sulla risposta dell'eccezione (e.response), risparmiando il get_item successivo dopo un controllo fallito. Non consuma alcuna capacità di lettura; una scrittura condizionale fallita fattura comunque il suo tentativo di scrittura.
  • Sull'API resource la stessa protezione è table.update_item(..., ConditionExpression=Attr("Version").eq(7) & Attr("Artist").exists()) con valori Python nativi.

Fallo visivamente

Le espressioni di condizione sono esattamente ciò che costruisce il DynamoDB Expression Builder — scegli la funzione, ottieni l'espressione + le mappe di nomi/valori come codice boto3 eseguibile.

Per modificare gli Item con espressioni generate e verificabili invece di segnaposto digitati a mano — scarica DynoTable.

Esempi correlati

References

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

Lavora con DynamoDB senza la Console

DynoTable è un client desktop veloce per DynamoDB — sfoglia le tabelle, esegui query in stile SQL e modifica gli Item localmente.