Expressões de atualização DynamoDB: SET, REMOVE, ADD, DELETE (com exemplos)
Uma expressão de atualização informa ao UpdateItem como transformar um único item: qual
para escrever, incrementar, excluir ou dobrar em um conjunto. Não há várias linhas
UPDATE … SET … WHERE — você nomeia um único item pela sua chave completa e descreve o
mude com palavras-chave de quatro cláusulas.
Como funcionam as expressões de atualização do DynamoDB?
Uma expressão de atualização DynamoDB informa ao UpdateItem como alterar um item usando quatro cláusulas. SET grava ou substitui um . ADD incrementa atomicamente um número ou uniões em um conjunto. REMOVE exclui um atributo ou um elemento da lista. DELETE remove membros específicos de um conjunto. Uma chamada pode transportar todos os quatro de uma vez.
SETgrava ou sobrescreve um atributo — escalares, documentos e idiomas de funçãoif_not_existselist_append.ADDfaz um incremento de número atômico ou uma união de conjunto, em uma viagem de ida e volta, sem leitura inicial.REMOVEexclui um atributo imediatamente (ou um único elemento da lista por índice).DELETEremove membros específicos de um conjunto — e somente de um conjunto.
Vindo do SQL, a armadilha chega ao SET para tudo. ADD e
DELETE existe porque ler-modificar-escrever em um contador ou conjunto é uma corrida que você
perder sob concorrência.
Escolha a cláusula de acordo com o que você está alterando
Uma chamada UpdateItem pode transportar todas as quatro cláusulas de uma vez, em qualquer ordem. Cada
palavra-chave aparece no máximo uma vez e leva uma lista de ações separadas por vírgula.
| Cláusula | Funciona em | Use-o para |
|---|---|---|
SET | Qualquer atributo | Write/overwrite um valor ou campo de documento |
ADD | Somente número ou conjunto | Incremento atomicamente ou união em um conjunto |
REMOVE | Qualquer atributo ou elemento de lista | Exclua um atributo; eliminar um índice de lista |
DELETE | Definir apenas | Remover membros específicos de um conjunto |
ADD em uma string e DELETE em um escalar são erros de validação, não no-ops -
DynamoDB rejeita toda a chamada. De acordo com
Referência de expressão de atualização AWS,
O ADD está restrito a números e conjuntos, e o DELETE a conjuntos.
O exemplo resolvido: um carrinho de compras
Um item por carrinho, codificado por CartPK = "CART#c-9f21" e CartSK = "SUMMARY".
Ele rastreia um OrderTotal em execução, uma lista LineItems, um conjunto de strings PromoCodes,
e um ItemCount.
SET — escreve os escalares e documentos
SET substitui tudo o que estava lá. Adicione um item de linha à lista e aumente o
total na mesma chamada:
SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now
list_append(LineItems, :newItem) é anexado à cauda; inverta os argumentos -
list_append(:newItem, LineItems) — para preceder. A ordem dos argumentos é a
ordem de concatenação, nada mais.
Há uma arma de fogo naquela primeira ligação: se o carrinho for novo, LineItems
ainda não existe e o list_append falha em um atributo ausente. Guarde-o com
if_not_exists:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)
if_not_exists(LineItems, :empty) retorna a lista atual, se presente, caso contrário, o
fallback :empty (uma lista vazia []). Isso faz com que a primeira adição e depois
add use a mesma expressão - uma verdadeira razão pela qual essas expressões existem.
ADD — incrementa a contagem, atomicamente
Para bater o ItemCount, não leia, adicione um em seu código e SET de volta.
Essa é uma corrida de atualização perdida: duas adições simultâneas leem 3, ambas escrevem 4 e
você deixou cair um. ADD faz a aritmética no lado do servidor:
ADD ItemCount :one
Com :one = 1, este é um contador atômico. Chamadas simultâneas são serializadas no
item, então dois adicionam terreno como +2. Passe um número negativo para decrementar. Se
ItemCount está ausente, ADD trata-o como 0 primeiro – então você nunca precisa semear
o contador.
Sob demanda no us-east-1, cada ADD cobra 1 WCU por KB do item após
a gravação (arredondada). Um resumo do carrinho de 1 KB com custos de um ADD ItemCount :one
1 WCU — a mesma linha com um SET de leitura-modificação-gravação custaria o mesmo WCU
mas perde sob concorrência. Dimensione o item no
calculadora de tamanho de item.
Você pode construir esta expressão exata - nomes, valores digitados e o empacotamento
solicitação - no
Construtor de expressão DynamoDB sem
escapar manualmente de um único espaço reservado #name ou :value.
Edite o preset abaixo - um SET mais um ADD atômico - e assista ao
UpdateExpression reconstruído conforme você avança:
REMOVE — elimina um atributo ou um item de linha
REMOVE é como você exclui totalmente um atributo (não há "defini-lo como nulo" -
que apenas escreve um tipo NULL). Limpe um desconto aplicado e descarte o terceiro
item de linha em uma chamada:
REMOVE AppliedDiscount, LineItems[2]
LineItems[2] remove o elemento no índice 2 e muda tudo depois dele
para baixo — o índice 3 se torna 2 e assim por diante. Se você usar REMOVE em dois índices em uma
expressão, ambos são avaliados em relação à lista original, portanto remover [2] e [3] juntos elimina o terceiro e o quarto elementos como seria de esperar.
DELETE — remove membros do conjunto
PromoCodes é um conjunto de strings, portanto, um cliente que obtém um código usa DELETE, não
REMOVE. REMOVE PromoCodes destruiria todo o conjunto; DELETE subtrai o
membros nomeados:
DELETE PromoCodes :pulled
Com :pulled = o conjunto {"SAVE10"}, apenas esse membro vai. Duas regras mordem
aqui: um conjunto nunca pode estar vazio, então excluir o último membro remove o
Atributo PromoCodes definitivo; e o valor deve ser um tipo de conjunto correspondente ao
atributo - uma string vazia é um erro de tipo.
Junte tudo
Uma atualização "adicionar item, aplicar uma promoção, aumentar a contagem" é uma chamada entre três cláusulas:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode
Nota OrderTotal = OrderTotal + :price - aritmética dentro de SET funciona no
valor existente. É tão atômico e seguro para corridas quanto o ADD: avalia o DynamoDB
OrderTotal + :price do lado do servidor em relação ao valor atual, portanto, chamadas simultâneas
serialize no item em vez de percorrer seu código.
Armadilhas a evitar
SET-ing um contador que você lê primeiro. UseADD- leitura-modificação-gravação perde atualizações sob simultaneidade. Este é o bug cart/inventory mais comum.list_appendem uma lista ausente. Envolva o alvo emif_not_existsou no a primeira gravação falha.- Confundir
REMOVEeDELETE.REMOVEelimina o atributo;DELETEsubtrai membros de um conjunto. Misturá-los exclui mais do que você pretendia. - Esquecer
UpdateItemé um upsert. Se a chave não existir, ela cria o item. Use umConditionExpression(attribute_exists(CartPK)) quando você significa "somente atualização".
Para modelar as chaves nas quais essas expressões são executadas, consulte design de mesa única; para decidir como você vai ler o carrinho de volta, consulte query vs scan.
Construa e copie qualquer um deles no construtor de expressão, então experimente DynoTable para executá-los em suas próprias mesas e observe o item mudar ao vivo.