PutItem DynamoDB in Node.js (AWS SDK v3)
PutItem scrive un Item intero e sostituisce qualsiasi Item esistente con la stessa chiave primaria (le azioni basate sugli Item spiegano in cosa differisce da UpdateItem). Il client v3 invia direttamente DynamoDB JSON, quindi Item contiene valori { S: … } / { N: … } invece di semplice JavaScript.
Codice
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;
}
}Spiegazione
err.name è il controllo giusto, e non è l'unica cosa presente sull'errore. Catturare la condizione fallita qui sopra e stampare l'oggetto ha dato:
err.name ConditionalCheckFailedException
err instanceof Error true
err.message The conditional request failed
err.$metadata.httpStatusCode 400Ogni errore v3 porta $metadata con il codice di stato, l'id della richiesta e il numero di tentativi, che è ciò che vuoi in una riga di log. err.name è stabile tra i pacchetti modulari; anche instanceof ConditionalCheckFailedException funziona, ma tira dentro la classe come import di valore, quindi i bundler la mantengono.
L'errore può consegnarti l'Item che ha bloccato la scrittura. Aggiungi ReturnValuesOnConditionCheckFailure: 'ALL_OLD' al comando e err.Item arriva popolato: cinque attributi nell'esecuzione qui sopra, con Year come {"N":"1994"}. La maggior parte degli handler di sola creazione fa un GetItem dopo il fallimento per scoprire cosa c'era già. Quel round trip è evitabile. (ReturnValues: 'ALL_OLD' è il cugino del percorso di successo; ReturnValues copre il resto.)
marshall() rifiuta più input di quanto ti aspetti. Scambiare l'Item tipizzato di questa pagina con DynamoDBDocumentClient e oggetti semplici è il passo successivo tipico, e @aws-sdk/util-dynamodb è strict per impostazione predefinita. Tre eccezioni reali, alla lettera:
{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.La prima è quella che arriva in produzione: un campo opzionale che è undefined invece che assente solleva un'eccezione al momento del marshalling, e removeUndefinedValues: true in DynamoDBDocumentClient.from(client, {marshallOptions}) è la correzione standard.
Rileggi la terza riga. Il letterale era 9007199254740993; il messaggio cita 9007199254740992. JavaScript aveva già arrotondato il valore prima che l'SDK lo vedesse, quindi l'SDK riporta ciò che ha ricevuto. È tutta qui la ragione per cui DynamoDB trasporta N come stringa: regge 38 cifre di precisione, mentre un number JS ne regge da 15 a 17. Tutto ciò che è davvero un identificatore appartiene a S, e tutto ciò che è davvero un decimale appartiene a NumberValue o a una stringa che formatti tu.
ConditionExpression costa capacità di scrittura anche quando dice di no. AWS: "if the expression evaluates to false, DynamoDB still consumes write capacity units from the table" (recuperato il 2026-07-28). Un loop stretto di retry di sola creazione viene fatturato per tentativo. Per calibrazione, un put riuscito di un Item da ~15 KB ha riportato "CapacityUnits": 15; le scritture arrotondano per eccesso ogni 1 KB invece dei 4 KB che usano le letture.
Gli alias sono portanti. #cond0/#cond1 si risolvono in Artist/SongTitle tramite ExpressionAttributeNames. I nomi inline funzionano finché uno non collide con una parola riservata, e a quel punto l'espressione fallisce su un attributo che non hai nemmeno toccato.
Fallo visivamente
Le regole di marshalling qui sopra sono più facili da verificare vedendo entrambe le forme affiancate. Il convertitore DynamoDB JSON gratuito trasforma JSON semplice nella forma tipizzata { S: … } e viceversa, così puoi confermare cosa avrebbe prodotto marshall() prima di inviarlo.
Per scrivere e modificare Item sulle tue tabelle — un modulo per attributo, selettori di tipo, il risultato ricopiabile come codice SDK v3 — scarica DynoTable.
Guide correlate
- Espressioni di condizione DynamoDB —
attribute_not_exists, optimistic locking e altro. - Tipi di dati DynamoDB — come viene scritto ogni tipo di attributo.
- DynamoDB ConditionalCheckFailedException — cosa solleva la condizione di sola creazione quando l'Item esiste già.
- DynamoDB ValidationException — il catch-all per un Item o un'espressione malformati.
Riferimenti
- 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
Riprodotto il 2026-07-28 su Node v24.18.0 con @aws-sdk/client-dynamodb 3.1095.0 e @aws-sdk/util-dynamodb 3.996.7, contro DynamoDB Local (amazon/dynamodb-local) sulla porta 9000. Le stringhe di errore, la forma dell'oggetto e la lettura di capacità sono output catturato, copiato alla lettera.