Escrita condicional no DynamoDB com a AWS CLI
Uma escrita condicional é simples de enviar pelo shell e desconfortável de ler, porque o resultado interessante de uma que falha chega como erro, e não como saída. Expressões de condição do DynamoDB cobre o que a expressão pode dizer; esta página é sobre executar uma pela CLI e extrair da falha o item perdedor.
Código
aws dynamodb update-item \
--table-name 'Music' \
--key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
--update-expression 'SET #upd0 = :updValue0, #version = :newVersion' \
--condition-expression 'attribute_exists(#cond0) AND #version = :expectedVersion' \
--expression-attribute-names '{"#upd0":"Genre","#version":"Version","#cond0":"Artist"}' \
--expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":expectedVersion":{"N":"7"},":newVersion":{"N":"8"}}'Em caso de sucesso o comando não imprime nada e sai com 0. Se outro escritor chegou primeiro, a condição falha e a CLI reporta a mensagem do serviço:
An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failedExplicação
- O sucesso é silencioso. Sem saída, código de saída 0. Não há nada para fazer parse nem nada para verificar, então um script de shell tem que tratar o código de saída como o resultado. Adicione
--return-values ALL_NEWse você quiser o item atualizado impresso. - A falha é o código de saída 254, que é o código da CLI v2 para um erro do lado do cliente e é compartilhado com uma requisição malformada. Ramifique com base na mensagem antes de tentar novamente, ou um erro de digitação na sua expressão vira um loop de backoff infinito.
--return-values-on-condition-check-failure ALL_OLDfunciona aqui, sim. Os valores válidos sãoALL_OLDeNONE, e ele não consome capacidade de leitura. Extrair o item do erro exige mais uma flag, coberta abaixo.- A condição e a atualização são flags separadas com um namespace compartilhado.
--expression-attribute-namese--expression-attribute-valuessão mesclados entre--update-expressione--condition-expression, e é por isso que os nomes gerados vão de#upd0a#cond0em vez de recomeçar por cláusula. Reutilize um placeholder para dois significados diferentes e o segundo vence silenciosamente. - Uma escrita que falha ainda é cobrada. O Developer Guide é explícito: uma condição que avalia como falsa consome capacidade de escrita de qualquer forma, dimensionada pelo maior entre o item antigo e o novo. Condições não são uma sondagem barata de existência.
A saída da falha, e como extrair o item dela
Execute o bloco uma vez e ele tem sucesso silenciosamente. Execute-o uma segunda vez, quando Version não é mais 7, e a aws-cli/2.36.9 imprime no stderr:
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failedAdicione --return-values-on-condition-check-failure ALL_OLD e a saída padrão te avisa que há mais, sem mostrar:
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed
Additional error details:
Item: <complex value>
Use "--cli-error-format json" or another error format to see the full details.<complex value> é o item, retido pelo renderizador de texto padrão. Adicione --cli-error-format json e a coisa toda é impressa:
{
"Message": "The conditional request failed",
"Code": "ConditionalCheckFailedException",
"Item": {
"Artist": {"S": "Arturo Sandoval"},
"Year": {"N": "1994"},
"Version": {"N": "8"},
"SongTitle": {"S": "Cubano Chant"},
"AlbumTitle": {"S": "Danzon"},
"Genre": {"S": "Latin Jazz"}
}
}(Mapas de atributos dobrados em uma linha cada; todo o resto é como foi impresso.) Version é 8 e Genre está definido porque a primeira execução teve sucesso. Esse é o loop de bloqueio otimista fechado a partir de um script de shell: encaminhe o stderr por jq -r '.Item.Version.N', devolva o valor como :expectedVersion, tente de novo. Sem get-item, e sem janela entre a leitura e a nova tentativa para um terceiro escritor se enfiar.
As novas tentativas não são de graça. Cada tentativa rejeitada consome uma unidade de escrita, então uma chave disputada em um loop apertado é cobrada continuamente sem fazer progresso algum. A calculadora de preços transforma uma taxa de escrita em um valor mensal se você quiser saber quanto uma tempestade de retries custa de verdade antes de limitar as tentativas.
Para executar essas proteções contra as suas próprias tabelas sem escapar os mapas de placeholders no shell, baixe o DynoTable.
Exemplos relacionados
- Escrita condicional no DynamoDB em Node.js — o mesmo bloqueio otimista com o AWS SDK v3.
- Escrita condicional no DynamoDB em Python — o mesmo bloqueio otimista com boto3.
- PutItem do DynamoDB com a AWS CLI — o put de
attribute_not_existsapenas para criação. - Expressões de condição do DynamoDB — todas as funções, com padrões.
- Entendendo ReturnValues — o que cada opção de retorno te dá.
- DynamoDB ConditionalCheckFailedException — quando a checagem falha por esperado, e como lidar com isso de forma barata.
Referências
- UpdateItem — Amazon DynamoDB API Reference
- update-item — AWS CLI Command Reference
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Verificado pela última vez em 2026-07-28 contra a documentação oficial da AWS vinculada acima.