Escritura condicional en DynamoDB en Python (boto3)
Una escritura condicional adjunta una ConditionExpression a un put_item, update_item o delete_item: DynamoDB la evalúa contra el item actual y aplica la escritura solo si se cumple — atómicamente, sin una carrera de lectura-modificación-escritura. Es la primitiva de bloqueo optimista de DynamoDB. Este ejemplo protege una actualización con una comprobación de versión.
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"))Explicación
ConditionExpression— comprobada contra el item almacenado atómicamente con la escritura. Funciones disponibles:attribute_exists,attribute_not_exists,attribute_type,contains,begins_with,size, más comparadores (=,<>,<,>,<=,>=,BETWEEN,IN) yAND/OR/NOT.- Los dos idiomas de caballo de batalla:
attribute_exists(#key)en una actualización = "solo actualizar, nunca crear". Sin ella,update_itemsobre una clave inexistente crea silenciosamente el item (el bug del upsert accidental).attribute_not_exists(#key)en una inserción = "solo crear, nunca sobrescribir" — mostrado en la página de PutItem.
- Bloqueo optimista — lee el item (versión 7), luego escribe con
#version = :expectedVersionmientras lo subes a 8. Dos escritores concurrentes no pueden ganar ambos; el perdedor recibeConditionalCheckFailedException, vuelve a leer y reintenta sobre la nueva versión. ReturnValuesOnConditionCheckFailure="ALL_OLD"— pone el item actual en la respuesta de la excepción (e.response), ahorrando elget_itemposterior tras una comprobación fallida. No consume capacidad de lectura; una escritura condicional fallida sigue facturando su intento de escritura.- En la API de recurso, la misma protección es
table.update_item(..., ConditionExpression=Attr("Version").eq(7) & Attr("Artist").exists())con valores nativos de Python.
Hazlo visualmente
Las expresiones de condición son exactamente lo que construye el DynamoDB Expression Builder — elige la función, obtén la expresión + los mapas de nombre/valor como código boto3 ejecutable.
Para editar items con expresiones generadas y revisables en lugar de marcadores de posición escritos a mano — descarga DynoTable.
Ejemplos relacionados
- Escritura condicional en DynamoDB en Node.js — el mismo bloqueo optimista con AWS SDK v3.
- Escritura condicional en DynamoDB con la AWS CLI — el mismo bloqueo optimista desde el shell.
- DynamoDB PutItem en Python — la inserción de solo crear con
attribute_not_exists. - Expresiones de condición de DynamoDB — cada función, con patrones.
- Imponer unicidad en varios atributos — condiciones + transacciones combinadas.
- DynamoDB ConditionalCheckFailedException — cuándo la comprobación fallida es esperada y cómo manejarla de forma barata.
References
- UpdateItem — Amazon DynamoDB API Reference
- DynamoDB.Client.update_item — Boto3 documentation
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Verificado por última vez el 2026-07-13 contra la documentación oficial de AWS enlazada arriba.