Intermedio3 min de lectura

ReturnValues de DynamoDB: recupera el elemento antiguo o nuevo de una escritura

Por defecto, una escritura de DynamoDB no devuelve más que el éxito. Pero a menudo necesitas los datos alrededor de la escritura — el valor antes de cambiarlo, o el valor fresco después. El arreglo ingenuo es un segundo GetItem, que es un viaje de ida y vuelta extra y una condición de carrera: otro proceso puede escribir en medio. DynamoDB evita ambos con el parámetro ReturnValues, que te devuelve el elemento antiguo o nuevo de forma atómica como parte de la propia escritura.

¿Qué hace ReturnValues en DynamoDB?

ReturnValues indica a una escritura de DynamoDB que devuelva el elemento como parte de la misma llamada, de modo que te ahorras un segundo GetItem y la condición de carrera que crea. PutItem y DeleteItem aceptan NONE o ALL_OLD; UpdateItem acepta las cinco opciones (NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW), devolviendo los valores anteriores o nuevos de forma atómica.

  • ReturnValues devuelve el elemento como parte de la escritura — sin segunda lectura, sin condición de carrera.
  • NONE (por defecto) — no devuelve nada.
  • ALL_OLD — el elemento entero tal como estaba antes de la escritura.
  • UPDATED_OLD — solo los atributos que la actualización cambió, valores anteriores.
  • ALL_NEW — el elemento entero después de la escritura.
  • UPDATED_NEW — solo los atributos cambiados, valores posteriores.
  • PutItem/DeleteItem aceptan solo NONE o ALL_OLD; UpdateItem acepta las cinco.

El problema: necesitas el valor que acabas de sobrescribir

Digamos que gestionas un servicio de soporte y un agente cambia el estado de un ticket de open a pending. Tu registro de auditoría necesita anotar cuál era el estado antes del cambio. Sin ReturnValues harías:

  1. GetItem para leer el estado actual,
  2. UpdateItem para establecer el nuevo.

Entre los pasos 1 y 2 otro agente podría cambiar el estado — ahora tu registro de auditoría anota un valor "anterior" obsoleto. Peor aún, son dos llamadas para una operación lógica. ReturnValues lo colapsa en un único UpdateItem atómico que devuelve el estado antiguo tal como realmente estaba en el momento de la escritura.

Las cinco opciones, y cuándo usar cada una

UpdateItem admite el conjunto completo; la elección es qué porción del elemento y qué lado de la escritura necesitas:

ReturnValuesDevuelveÚsalo cuando
NONEnadano necesitas el elemento de vuelta (por defecto)
ALL_OLDelemento entero, pre-escrituraauditoría / "¿qué acabo de reemplazar?"
UPDATED_OLDatributos cambiados, pre-escriturasolo te importan los campos que tocaste
ALL_NEWelemento entero, post-escrituranecesitas el elemento completo y fresco para devolverlo a un llamador
UPDATED_NEWatributos cambiados, post-escrituraleer de vuelta un contador/valor que acabas de incrementar

UPDATED_NEW es el héroe del día a día: incrementa un contador con una expresión de actualización y lee el nuevo total de vuelta en la misma llamada, sin condición de carrera. Para la auditoría del ticket de soporte, ALL_OLD (o UPDATED_OLD si solo registras el campo de estado) captura el estado previo al cambio de forma atómica.

Fíjate en la asimetría: PutItem y DeleteItem solo admiten NONE y ALL_OLD — no hay valor "nuevo" que devolver para un delete, y el valor nuevo de un put es justo lo que enviaste. Solo UpdateItem, que muta in situ, ofrece las cinco. AWS documenta la matriz exacta.

Escribir la actualización en DynoTable

Ensambla el UpdateItem y su expresión de actualización visualmente con el constructor de expresiones de DynamoDB — emite la cláusula SET/ADD más los mapas de nombres y valores de atributos. En la app, DynoTable muestra el elemento resultante después de confirmar una escritura preparada, así que ves el nuevo estado directamente.

Revisando el cambio preparado de un item en DynoTable — los valores antiguo y nuevo antes de confirmar la actualización.
Revisando el cambio preparado de un item en DynoTable — los valores antiguo y nuevo antes de confirmar la actualización.

Trampas y próximos pasos

  • No hagas GetItem-luego-escribir para leer alrededor de un cambio — es un viaje de ida y vuelta y una condición de carrera; usa ReturnValues.
  • UPDATED_* devuelve solo los atributos tocados — si necesitas el elemento entero, usa ALL_*.
  • PutItem/DeleteItem no pueden devolver valores nuevos — solo NONE/ALL_OLD.
  • ReturnValues no sustituye a una condición — para proteger una escritura, añade una expresión de condición; para leer de vuelta su efecto, usa ReturnValues. Se componen.
  • Relacionado: expresiones de actualización, contadores atómicos.

¿Quieres hacer ediciones y ver el antes/después sin programar dos llamadas? Descarga DynoTable y edita tus elementos directamente.

Actualizado