DynamoDB Actualizar expresiones: SET, REMOVE, ADD, DELETE (con ejemplos)
Una expresión de actualización le dice a UpdateItem cómo mutar un solo elemento: cuál
para escribir, incrementar, eliminar o plegar en un conjunto. No hay varias filas
UPDATE … SET … WHERE: nombras un solo elemento por su clave completa y describe el
cambie con la clave de cuatro cláusulasrds.
¿Cómo funcionan las DynamoDB expresiones de actualización?
Una expresión de actualización DynamoDB le dice a UpdateItem cómo mutar un elemento usando cuatro cláusulas. SET escribe o sobrescribe un . ADD incrementa atómicamente un número o uniones en un conjunto. REMOVE elimina un atributo o un elemento de la lista. DELETE elimina miembros específicos de un conjunto. Una llamada puede transportar los cuatro a la vez.
SETescribe o sobrescribe un atributo: escalares, documentos y el modismos de funciónif_not_existsylist_append.ADDhace un incremento de número atómico o una unión de conjunto, en un viaje de ida y vuelta, sin lectura primero.REMOVEelimina un atributo directamente (o un único elemento de lista por índice).DELETEelimina miembros específicos de un conjunto, y solo de un conjunto.
Viniendo de SQL, la trampa busca SET para todo. ADD y
DELETE existen porque leer-modificar-escribir en un contador o un conjunto es una carrera que
perder bajo concurrencia.
Elige la cláusula según lo que estás cambiando
Una llamada UpdateItem puede llevar las cuatro cláusulas a la vez, en cualquier orden. cada uno
La palabra clave aparece como máximo una vez y requiere una lista de acciones separadas por comas.
| Cláusula | Trabaja en | Úselo para |
|---|---|---|
SET | Cualquier atributo | Escribir/sobrescribir un valor o campo de documento |
ADD | Solo número o conjunto | Incremento atómico o unión en un conjunto |
REMOVE | Cualquier atributo o elemento de lista | Eliminar un atributo; soltar un índice de lista |
DELETE | Establecer solo | Eliminar miembros específicos de un conjunto |
ADD en una cadena y DELETE en un escalar son errores de validación, no operaciones no operativas.
DynamoDB rechaza toda la llamada. Según el
AWS referencia de expresión de actualización,
ADD está restringido a números y conjuntos, y DELETE a conjuntos.
El ejemplo resuelto: un carrito de compras
Un artículo por carrito, codificado por CartPK = "CART#c-9f21" y CartSK = "SUMMARY".
Realiza un seguimiento de una lista OrderTotal en ejecución, una lista LineItems, un conjunto de cadenas PromoCodes,
y un ItemCount.
SET: escribe los escalares y los documentos
SET sobrescribe lo que haya allí. Agregue una línea de pedido a la lista y elimine el
total en la misma convocatoria:
SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now
list_append(LineItems, :newItem) añade al final; invierte los argumentos —
list_append(:newItem, LineItems) — para añadir al principio. El orden de los argumentos
es el orden de la concatenación, nada más.
Hay una trampa en esa primera llamada: si el carrito es nuevo, LineItems todavía no
existe, y list_append sobre un atributo ausente falla. Protégelo con if_not_exists:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)
if_not_exists(LineItems, :empty) devuelve la lista actual si existe, y si no el valor de
reserva :empty (una lista vacía []). Eso hace que la primera adición y todas las
posteriores usen la misma expresión: una razón real de que existan estos modismos.
ADD — incrementa el recuento, de forma atómica
Para subir ItemCount, no lo leas, sumes uno en tu código y lo vuelvas a escribir con
SET. Eso es una carrera de actualización perdida: dos adiciones concurrentes leen 3,
ambas escriben 4 y has perdido una. ADD hace la aritmética en el lado del servidor:
ADD ItemCount :one
Con :one = 1, esto es un contador atómico. Las llamadas concurrentes se serializan
sobre el elemento, así que dos adiciones aterrizan como +2. Pasa un número negativo para
decrementar. Si ItemCount no existe, ADD lo trata primero como 0, así que nunca
necesitas inicializar el contador.
Bajo demanda en us-east-1, cada ADD factura 1 WCU por KB del elemento después de la
escritura (redondeado hacia arriba). Un resumen de carrito de 1 KB con un
ADD ItemCount :one cuesta 1 WCU: la misma fila con un SET de leer-modificar-escribir
costaría los mismos WCU pero perdería bajo concurrencia. Dimensiona el elemento en la
calculadora de tamaño de elemento.
Puedes construir esta misma expresión — nombres, valores tipados y la petición marshalled —
en el generador de expresiones de DynamoDB sin
escapar a mano ni un solo marcador #name o :value.
Edita el preajuste de abajo — un SET más un ADD atómico — y observa cómo se reconstruye
la UpdateExpression sobre la marcha:
REMOVE — elimina un atributo o una línea de pedido
REMOVE es como se borra un atributo por completo (no existe el "ponlo a null": eso solo
escribe un tipo NULL). Borra un descuento aplicado y elimina la tercera línea de pedido
en una sola llamada:
REMOVE AppliedDiscount, LineItems[2]
LineItems[2] elimina el elemento del índice 2 y desplaza hacia abajo todo lo que va
detrás: el índice 3 pasa a ser 2, y así sucesivamente. Si haces REMOVE de dos índices
en una misma expresión, ambos se evalúan contra la lista original, así que eliminar
[2] y [3] juntos quita el tercer y el cuarto elemento, como esperarías.
DELETE — quita miembros de un conjunto
PromoCodes es un conjunto de cadenas, así que un cliente que retira un código usa
DELETE, no REMOVE. REMOVE PromoCodes arrasaría con el conjunto entero; DELETE resta
los miembros nombrados:
DELETE PromoCodes :pulled
Con :pulled = el conjunto {"SAVE10"}, solo se va ese miembro. Aquí muerden dos reglas:
un conjunto nunca puede estar vacío, así que borrar el último miembro elimina el atributo
PromoCodes por completo; y el valor debe ser un tipo conjunto que coincida con el
atributo — una cadena suelta es un error de tipo.
Júntalo todo
Una actualización de "añade el artículo, aplica una promoción, sube el recuento" es una sola llamada repartida en tres cláusulas:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode
Fíjate en OrderTotal = OrderTotal + :price: la aritmética dentro de SET opera sobre el
valor existente. Es igual de atómica y segura frente a carreras que ADD: DynamoDB evalúa
OrderTotal + :price en el lado del servidor contra el valor actual, así que las llamadas
concurrentes se serializan sobre el elemento en lugar de dar un rodeo por tu código.
Escollos a evitar
- Hacer
SETde un contador que has leído antes. UsaADD: leer-modificar-escribir pierde actualizaciones bajo concurrencia. Es el error de carrito/inventario más común. list_appendsobre una lista ausente. Envuelve el destino enif_not_existso la primera escritura falla.- Confundir
REMOVEyDELETE.REMOVEelimina el atributo;DELETEresta miembros de un conjunto. Mezclarlos borra más de lo que pretendías. - Olvidar que
UpdateItemes un upsert. Si la clave no existe, crea el elemento. Usa unaConditionExpression(attribute_exists(CartPK)) cuando quieras decir "solo actualizar".
Para modelar las claves con las que se ejecutan estas expresiones, consulte diseño de tabla única; para decidir cómo leerás el carrito de vuelta, vea query vs scan.
Construya y copie cualquiera de estos en el generador de expresiones, luego pruebe DynoTable para ejecutarlos en sus propias tablas y observar el elemento. cambiar en vivo.