PutItem do DynamoDB em Node.js (AWS SDK v3)
O PutItem escreve um item inteiro e substitui qualquer item existente com a mesma chave primária (ações baseadas em item cobre como isso difere do UpdateItem). O cliente v3 envia DynamoDB JSON diretamente, então Item contém valores { S: … } / { N: … } em vez de JavaScript puro.
Código
import {DynamoDBClient, PutItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const command = new PutItemCommand({
TableName: 'Music',
Item: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'},
AlbumTitle: {S: 'Danzon'},
Year: {N: '1994'},
Awards: {N: '0'}
},
ConditionExpression: 'attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)',
ExpressionAttributeNames: {
'#cond0': 'Artist',
'#cond1': 'SongTitle'
}
});
try {
await client.send(command);
console.log('Song written');
} catch (err) {
if (err.name === 'ConditionalCheckFailedException') {
console.log('A song with that key already exists — not overwritten');
} else {
throw err;
}
}Explicação
err.name é a verificação certa, e não é a única coisa no erro. Capturar a condição que falhou acima e imprimir o objeto deu:
err.name ConditionalCheckFailedException
err instanceof Error true
err.message The conditional request failed
err.$metadata.httpStatusCode 400Todo erro v3 carrega $metadata com o código de status, o id da requisição e a contagem de tentativas, que é o que você quer em uma linha de log. err.name é estável entre os pacotes modulares; instanceof ConditionalCheckFailedException também funciona, mas puxa a classe como import de valor, então os bundlers a mantêm.
O erro pode te entregar o item que bloqueou a escrita. Adicione ReturnValuesOnConditionCheckFailure: 'ALL_OLD' ao comando e err.Item chega preenchido: cinco atributos na execução acima, com Year como {"N":"1994"}. A maioria dos handlers de criação-apenas faz um GetItem depois da falha para descobrir o que já estava lá. Esse ida-e-volta é evitável. (ReturnValues: 'ALL_OLD' é o primo do caminho de sucesso; ReturnValues cobre o resto.)
O marshall() recusa mais entradas do que você espera. Trocar o Item tipado desta página por DynamoDBDocumentClient e objetos simples é o próximo passo habitual, e o @aws-sdk/util-dynamodb é estrito por padrão. Três erros reais, literais:
{Genre: undefined} Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.
{tags: new Set()} Pass a non-empty set, or options.convertEmptyValues=true.
{n: 9007199254740993} Number 9007199254740992 is greater than Number.MAX_SAFE_INTEGER. Use NumberValue from @aws-sdk/lib-dynamodb.O primeiro é o que chega em produção: um campo opcional que é undefined em vez de ausente lança erro no momento do marshal, e removeUndefinedValues: true em DynamoDBDocumentClient.from(client, {marshallOptions}) é a correção padrão.
Leia a terceira linha de novo. O literal era 9007199254740993; a mensagem cita 9007199254740992. O JavaScript já tinha arredondado o valor antes de o SDK sequer vê-lo, então o SDK está reportando o que recebeu. Essa é toda a razão pela qual o DynamoDB transporta N como string: ele guarda 38 dígitos de precisão, e um number do JS guarda de 15 a 17. Qualquer coisa que é de fato um identificador pertence a S, e qualquer coisa que é de fato um decimal pertence a NumberValue ou a uma string que você mesmo formata.
ConditionExpression custa capacidade de escrita mesmo quando diz não. AWS: "if the expression evaluates to false, DynamoDB still consumes write capacity units from the table" (consultado em 2026-07-28). Um loop apertado de retry de criação-apenas é cobrado por tentativa. Para calibrar, um put bem-sucedido de um item de ~15 KB reportou "CapacityUnits": 15; escritas arredondam para cima a cada 1 KB em vez dos 4 KB que as leituras usam.
Os aliases são estruturais. #cond0/#cond1 resolvem para Artist/SongTitle através de ExpressionAttributeNames. Nomes inline funcionam até que um colida com uma palavra reservada, e aí a expressão falha em um atributo que você nem tocou.
Faça isso visualmente
As regras de marshalling acima são mais fáceis de conferir vendo as duas formas lado a lado. O conversor de DynamoDB JSON gratuito transforma JSON simples na forma tipada { S: … } e de volta, para que você possa confirmar o que o marshall() teria produzido antes de enviar.
Para escrever e editar itens nas suas próprias tabelas — um formulário por atributo, seletores de tipo, copiar o resultado de volta como código SDK v3 — baixe o DynoTable.
Guias relacionados
- Expressões de condição do DynamoDB —
attribute_not_exists, bloqueio otimista e mais. - Tipos de dados do DynamoDB — como cada tipo de atributo é escrito.
- DynamoDB ConditionalCheckFailedException — o que a condição de criação-apenas lança quando o item já existe.
- DynamoDB ValidationException — o pega-tudo para um item ou expressão malformados.
Referências
- PutItem — Amazon DynamoDB API Reference
- PutItemCommand — AWS SDK for JavaScript v3 Reference
- Capacity unit consumption — Amazon DynamoDB Developer Guide
- Condition expressions — Amazon DynamoDB Developer Guide
- Working with items and attributes — Amazon DynamoDB Developer Guide
Reproduzido em 2026-07-28 no Node v24.18.0 com @aws-sdk/client-dynamodb 3.1095.0 e @aws-sdk/util-dynamodb 3.996.7, contra o DynamoDB Local (amazon/dynamodb-local) na porta 9000. As strings de erro, o formato do objeto e a leitura de capacidade são saída capturada, copiada literalmente.