DynamoDB PutItem in Node.js (AWS SDK v3)
PutItem schreibt ein ganzes Item und ersetzt jedes bestehende Item mit demselben Primary Key (Item-basierte Aktionen behandelt, wie sich das von UpdateItem unterscheidet). Der v3-Client sendet DynamoDB JSON direkt, Item enthält also { S: … }- / { N: … }-Werte statt schlichtem JavaScript.
Code
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;
}
}Erklärung
err.name ist die richtige Prüfung — und nicht das Einzige am Fehler. Die fehlgeschlagene Bedingung oben abzufangen und das Objekt auszugeben ergab:
err.name ConditionalCheckFailedException
err instanceof Error true
err.message The conditional request failed
err.$metadata.httpStatusCode 400Jeder v3-Fehler trägt $metadata mit Statuscode, Request-ID und Versuchszähler — genau das, was du in einer Log-Zeile willst. err.name ist über die modularen Pakete hinweg stabil; instanceof ConditionalCheckFailedException funktioniert ebenfalls, zieht die Klasse aber als Value-Import herein, sodass Bundler sie behalten.
Der Fehler kann dir das Item liefern, das den Write blockiert hat. Ergänze ReturnValuesOnConditionCheckFailure: 'ALL_OLD' am Command und err.Item kommt befüllt an: fünf Attribute im obigen Lauf, mit Year als {"N":"1994"}. Die meisten nur-erzeugenden Handler machen nach dem Fehlschlag ein GetItem, um herauszufinden, was schon da war. Dieser Roundtrip ist vermeidbar. (ReturnValues: 'ALL_OLD' ist das Pendant auf dem Erfolgspfad; ReturnValues behandelt den Rest.)
marshall() verweigert mehr Eingaben, als du erwartest. Das typisierte Item dieser Seite gegen DynamoDBDocumentClient und schlichte Objekte zu tauschen ist der übliche nächste Schritt, und @aws-sdk/util-dynamodb ist standardmäßig streng. Drei echte Fehlerwürfe, wortgetreu:
{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.Der erste ist der, der es in Produktion schafft: ein optionales Feld, das undefined statt abwesend ist, wirft zum Marshal-Zeitpunkt, und removeUndefinedValues: true in DynamoDBDocumentClient.from(client, {marshallOptions}) ist die Standardlösung.
Lies die dritte Zeile noch einmal. Das Literal war 9007199254740993; die Nachricht zitiert 9007199254740992. JavaScript hatte den Wert bereits gerundet, bevor das SDK ihn überhaupt sah — das SDK meldet also, was es empfangen hat. Genau deshalb transportiert DynamoDB N als String: Es hält 38 Stellen Genauigkeit, eine JS-number hält 15 bis 17. Alles, was in Wahrheit ein Identifier ist, gehört in S, und alles, was in Wahrheit eine Dezimalzahl ist, gehört in NumberValue oder einen String, den du selbst formatierst.
ConditionExpression kostet Write-Kapazität, auch wenn sie nein sagt. AWS: "if the expression evaluates to false, DynamoDB still consumes write capacity units from the table" (abgerufen 2026-07-28). Eine enge nur-erzeugende Retry-Schleife wird pro Versuch abgerechnet. Zur Kalibrierung: Ein erfolgreiches Put eines ~15 KB großen Items meldete "CapacityUnits": 15; Writes runden pro 1 KB auf, statt der 4 KB, die Reads nutzen.
Die Aliase sind tragend. #cond0/#cond1 lösen über ExpressionAttributeNames zu Artist/SongTitle auf. Inline-Namen funktionieren, bis einer mit einem reservierten Wort kollidiert — und dann scheitert die Expression an einem Attribut, das du gar nicht angefasst hast.
Mach es visuell
Die Marshalling-Regeln oben prüft man am leichtesten, indem man beide Formen nebeneinander sieht. Der kostenlose DynamoDB-JSON-Konverter verwandelt schlichtes JSON in die typisierte { S: … }-Form und zurück, sodass du bestätigen kannst, was marshall() erzeugt hätte, bevor du es abschickst.
Um Items gegen deine eigenen Tabellen zu schreiben und zu bearbeiten — ein Formular pro Attribut, Typ-Auswahl, das Ergebnis als SDK-v3-Code zurückkopieren — lade DynoTable herunter.
Verwandte Leitfäden
- DynamoDB Condition Expressions —
attribute_not_exists, Optimistic Locking und mehr. - DynamoDB-Datentypen — wie jeder Attributtyp geschrieben wird.
- DynamoDB ConditionalCheckFailedException — was die nur-erzeugende Bedingung wirft, wenn das Item schon existiert.
- DynamoDB ValidationException — der Auffangfehler für ein fehlerhaftes Item oder eine fehlerhafte Expression.
Referenzen
- 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
Am 2026-07-28 auf Node v24.18.0 mit @aws-sdk/client-dynamodb 3.1095.0 und @aws-sdk/util-dynamodb 3.996.7 gegen DynamoDB Local (amazon/dynamodb-local) auf Port 9000 reproduziert. Die Fehlerstrings, die Objektform und der Kapazitätswert sind aufgezeichnete Ausgabe, wortgetreu kopiert.