Update Expressions DynamoDB : SET, REMOVE, ADD, DELETE (avec exemples)
Une expression de mise à jour indique à UpdateItem comment modifier un seul item : quels
écrire, incrémenter, supprimer ou fusionner dans un ensemble. Il n'existe pas de
UPDATE … SET … WHERE multi-lignes — tu nommes un unique item par sa clé complète et tu décris le
changement avec quatre mots-clés de clause.
Comment fonctionnent les expressions de mise à jour DynamoDB ?
Une expression de mise à jour DynamoDB indique à UpdateItem comment modifier un item à l'aide de quatre clauses. SET écrit ou remplace un . ADD incrémente atomiquement un nombre ou fait une union dans un ensemble. REMOVE supprime un attribut ou un élément de liste. DELETE retire des membres précis d'un ensemble. Un seul appel peut porter les quatre à la fois.
SETécrit ou remplace un attribut — scalaires, documents, et les idiomes de fonctionif_not_existsetlist_append.ADDeffectue une incrémentation atomique de nombre ou une union d'ensemble, en un seul aller-retour, sans lecture préalable.REMOVEsupprime un attribut pur et simple (ou un unique élément de liste par index).DELETEretire des membres précis d'un ensemble — et seulement d'un ensemble.
Quand tu viens de SQL, le piège est de te tourner vers SET pour tout. ADD et DELETE existent
parce que le lire-modifier-écrire sur un compteur ou un ensemble est une compétition que tu perdras
en cas de concurrence.
Choisis la clause selon ce que tu changes
Un seul appel UpdateItem peut porter les quatre clauses à la fois, dans n'importe quel ordre.
Chaque mot-clé apparaît au plus une fois et prend une liste d'actions séparées par des virgules.
| Clause | Agit sur | À utiliser pour |
|---|---|---|
SET | N'importe quel attribut | Écrire/remplacer une valeur ou un champ de document |
ADD | Nombre ou ensemble uniquement | Incrémenter atomiquement, ou faire une union dans un ensemble |
REMOVE | N'importe quel attribut ou élément de liste | Supprimer un attribut ; retirer un index de liste |
DELETE | Ensemble uniquement | Retirer des membres précis d'un ensemble |
ADD sur une chaîne et DELETE sur un scalaire sont des erreurs de validation, pas des
non-opérations — DynamoDB rejette tout l'appel. Selon la
référence des expressions de mise à jour AWS,
ADD est restreint aux nombres et aux ensembles, et DELETE aux ensembles.
L'exemple concret : un panier d'achat
Un item par panier, clé sur CartPK = "CART#c-9f21" et CartSK = "SUMMARY". Il suit un
OrderTotal courant, une liste LineItems, un ensemble de chaînes PromoCodes et un ItemCount.
SET — écrire les scalaires et les documents
SET remplace ce qui était là. Ajoute un article à la liste et augmente le total dans le même
appel :
SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now
list_append(LineItems, :newItem) ajoute à la fin ; inverse les arguments —
list_append(:newItem, LineItems) — pour ajouter au début. L'ordre des arguments est l'ordre de
concaténation, rien de plus.
Il y a un piège dans ce premier appel : si le panier est tout neuf, LineItems n'existe pas
encore, et list_append sur un attribut manquant échoue. Protège-le avec if_not_exists :
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)
if_not_exists(LineItems, :empty) renvoie la liste courante si elle est présente, sinon la valeur
de repli :empty (une liste vide []). Cela fait que le premier ajout et chaque ajout ultérieur
utilisent la même expression — une vraie raison d'être de ces idiomes.
ADD — incrémenter le compteur, atomiquement
Pour augmenter ItemCount, ne le lis pas, n'ajoute pas un dans ton code, et ne le réécris pas
avec SET. C'est une compétition avec perte de mise à jour : deux ajouts concurrents lisent tous
deux 3, écrivent tous deux 4, et tu en as perdu un. ADD fait l'arithmétique côté serveur :
ADD ItemCount :one
Avec :one = 1, c'est un compteur atomique. Les appels concurrents se sérialisent sur l'item,
si bien que deux ajouts atterrissent en +2. Passe un nombre négatif pour décrémenter. Si
ItemCount est absent, ADD le traite d'abord comme 0 — tu n'as donc jamais besoin d'initialiser
le compteur.
En on-demand dans us-east-1, chaque ADD facture 1 WCU par Ko de l'item après
l'écriture (arrondi au supérieur). Un résumé de panier de 1 Ko avec un seul
ADD ItemCount :one coûte 1 WCU — la même ligne en lecture-modification-écriture avec
SET coûterait le même WCU mais perdrait sous concurrence. Dimensionne l'item dans le
calculateur de taille d'élément.
Tu peux construire exactement cette expression — noms, valeurs typées et requête marshalled — dans
le générateur d'expressions DynamoDB sans échapper à la main
un seul placeholder #name ou :value.
Modifie le préréglage ci-dessous — un SET plus un ADD atomique — et regarde
l'UpdateExpression se reconstruire au fur et à mesure :
REMOVE — retirer un attribut ou un article
REMOVE est la façon de supprimer un attribut entièrement (il n'y a pas de « le mettre à null » —
cela écrit juste un type NULL). Efface une remise appliquée et retire le troisième article en un
seul appel :
REMOVE AppliedDiscount, LineItems[2]
LineItems[2] retire l'élément à l'index 2 et décale tout ce qui suit vers le bas — l'index 3
devient 2, et ainsi de suite. Si tu fais un REMOVE de deux index dans une même expression, les
deux sont évalués contre la liste d'origine, si bien que retirer [2] et [3] ensemble
supprime le troisième et le quatrième éléments comme prévu.
DELETE — retirer des membres d'ensemble
PromoCodes est un ensemble de chaînes, donc un client qui retire un code utilise DELETE, pas
REMOVE. REMOVE PromoCodes anéantirait tout l'ensemble ; DELETE soustrait les membres nommés :
DELETE PromoCodes :pulled
Avec :pulled = l'ensemble {"SAVE10"}, seul ce membre s'en va. Deux règles mordent ici : un
ensemble ne peut jamais être vide, si bien que supprimer le dernier membre retire l'attribut
PromoCodes pur et simple ; et la valeur doit être un type ensemble correspondant à l'attribut —
une simple chaîne est une erreur de type.
Assemble le tout
Une mise à jour « ajouter un article, appliquer une promo, augmenter le compteur » est un seul appel réparti sur trois clauses :
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode
Note OrderTotal = OrderTotal + :price — l'arithmétique dans SET opère sur la valeur existante.
C'est tout aussi atomique et à l'abri des compétitions qu'ADD : DynamoDB évalue
OrderTotal + :price côté serveur contre la valeur courante, si bien que les appels concurrents se
sérialisent sur l'item au lieu de faire l'aller-retour par ton code.
Pièges à éviter
- Faire un
SETd'un compteur que tu lis d'abord. UtiliseADD— le lire-modifier-écrire perd des mises à jour en cas de concurrence. C'est le bug de panier/inventaire le plus courant. list_appendsur une liste manquante. Enveloppe la cible dansif_not_existssinon la première écriture échoue.- Confondre
REMOVEetDELETE.REMOVEretire l'attribut ;DELETEsoustrait des membres d'un ensemble. Les mélanger supprime plus que tu ne le voulais. - Oublier qu'
UpdateItemest un upsert. Si la clé n'existe pas, il crée l'item. Utilise unConditionExpression(attribute_exists(CartPK)) quand tu veux dire « mettre à jour uniquement ».
Pour modéliser les clés contre lesquelles ces expressions s'exécutent, voir conception à table unique ; pour décider comment tu reliras le panier, voir query vs scan.
Construis et copie n'importe laquelle de celles-ci dans le générateur d'expressions, puis essaie DynoTable pour les exécuter contre tes propres tables et voir l'item changer en direct.