DynamoDB BatchWriteItem in Node.js (AWS SDK v3)
BatchWriteItem schreibt oder löscht bis zu 25 Items in einer Anfrage. Es ist kein kleineres UpdateItem: Jeder PutRequest ersetzt das komplette gespeicherte Item, und die v3-Typen geben dir keine Stelle, an der du eine Bedingung anhängen könntest. Batch-Operationen in DynamoDB behandelt die Limits und das Modell für partielles Scheitern; auf dieser Seite geht es um den v3-Aufruf und um die eine Art, wie er stillschweigend Daten verliert.
Code
import {BatchWriteItemCommand, DynamoDBClient} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let requestItems = {
Music: [
{
PutRequest: {
Item: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'},
AlbumTitle: {S: 'Danzon'},
Year: {N: '1994'}
}
}
},
{
PutRequest: {
Item: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'A Mis Abuelos'},
AlbumTitle: {S: 'Danzon'},
Year: {N: '1994'}
}
}
},
{
DeleteRequest: {
Key: {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}
}
}
]
};
let attempt = 0;
do {
const response = await client.send(new BatchWriteItemCommand({RequestItems: requestItems}));
// Writes that were throttled come back in UnprocessedItems — resubmit them
// with exponential backoff until the map is empty.
requestItems = response.UnprocessedItems;
if (requestItems && Object.keys(requestItems).length > 0) {
attempt += 1;
await sleep(Math.min(100 * 2 ** attempt, 5000));
}
} while (requestItems && Object.keys(requestItems).length > 0);
console.log('Batch written');Erklärung
- Das Rest-Member heißt
UnprocessedItems, nichtUnprocessedKeys. Die Leseseite nutzt den anderen Namen, und in JavaScript kompiliert ein Tippfehler hier, liest sich alsundefinedund macht aus demdo/whileeinen Aufruf mit einem einzigen Durchlauf, der gedrosselte Writes unter den Tisch fallen lässt. TypeScript fängt das ab; reines JS nicht. - Es gibt keinen Platz für eine Bedingung. Der v3-
WriteRequest-Typ hat genau zwei optionale Member,PutRequestundDeleteRequest, und keiner nimmtConditionExpressionoderReturnValuesan. Das ist keine Vorsicht des SDK: Die API-Referenz sagt, dass du für einzelne Put- und Delete-Requests keine Bedingungen angeben kannst. Wenn ein Write eine Absicherung braucht, gehört er nicht in ein Batch, sondern in UpdateItem mit einer Bedingung oder in eine Transaktion. - Zwei per
catchabfangbare Fehler, beide nicht wiederholbar, unterschieden übererr.name. Sechsundzwanzig Einträge lösenValidationException/Too many items requested for the BatchWriteItem callaus. Denselben Key zweimal anzufassen löstProvided list of item keys contains duplicatesaus, und diese Meldung deckt ein Put-plus-Delete-Paar genauso ab wie zwei Puts — was beim ersten Mal seltsam liest. - Die Liste der Gründe, ein ganzes Batch abzulehnen, ist länger als die offensichtlichen drei. Neben mehr als 25 Requests, einem Item über 400 KB und mehr als 16 MB insgesamt lehnt DynamoDB das Batch ab bei einer fehlenden Tabelle, einem Key, der nicht zum Schema passt, einem Partition Key über 2048 Bytes oder einem Sort Key über 1024 Bytes. Ein schlechter Eintrag kostet dich alle 25.
- Batching spart Round Trips, keine Kapazität. Jeder Eintrag wird als einzelnes
PutItemoderDeleteItemabgerechnet, aufgerundet auf 1 KB, und ein Delete auf ein nicht existierendes Item verbraucht trotzdem eine Schreibeinheit.
Ein PutRequest nur mit Keys zerstört den Rest des Items
Ella Fitzgerald / Misty hat anfangs einen AlbumTitle und ein Year. Schicke einen PutRequest, der nur die beiden Key-Attribute trägt:
{PutRequest: {Item: {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}}}Lies es dann mit ConsistentRead: true zurück. DynamoDB Local 3.3.0 liefert:
{
"Artist": { "S": "Ella Fitzgerald" },
"SongTitle": { "S": "Misty" }
}AlbumTitle und Year sind weg. Der Aufruf war erfolgreich, UnprocessedItems war {}, und nichts in der Antwort erwähnt die beiden Attribute, die sie fallen gelassen hat. Ein Put ist ein Ersetzen des kompletten Items — ein Batch, das aus einem unvollständigen Payload zusammengesetzt wurde (ein API-Request-Body, eine Teilmenge von CSV-Spalten, ein projiziertes Query-Ergebnis, das Attribute ausgelassen hat), löscht also jedes Attribut, das der Payload nicht mitbrachte.
Das ist der Fehlerfall, den du einplanen musst, wenn du ein Batch für etwas nutzt, das sich wie ein Update anfühlt. Die Lösung: erst das aktuelle Item lesen und mergen — oder das Batching lassen und UpdateItem nehmen, das nur die Attribute anfasst, die du benennst.
Der andere Grund, warum aus einem 25-Item-Batch ein 12-Item-Batch wird, ist die Größe. Writes werden für die Abrechnung auf je 1 KB aufgerundet und die Anfrage ist bei 16 MB gedeckelt — die echte Byte-Zahl eines Items entscheidet also über deine Rechnung und darüber, wie viele hineinpassen. Der Item-Size-Rechner liefert dir diese Zahl pro Item, bevor du das Array zusammenbaust.
Um Items in großer Zahl zu laden, zu bearbeiten und zu löschen, ohne die Ersetzungs-Semantik von Hand zu schreiben, lade DynoTable herunter.
Verwandte Beispiele
- DynamoDB Batch-Write in Python — boto3s
batch_writer()erledigt die Retry-Schleife für dich. - DynamoDB BatchWriteItem mit der AWS CLI — derselbe Batch-Write aus der Shell.
- DynamoDB TransactWriteItems in Node.js — wenn die Writes gemeinsam gelingen oder gemeinsam scheitern müssen.
- Batch-Operationen in DynamoDB — Limits, partielles Scheitern und wann sich Batching lohnt.
- „Too many items requested for the BatchWriteItem call" — mehr als 25 Put-/Delete-Requests in einem Batch.
- „Provided list of item keys contains duplicates" — zwei Requests auf denselben Key in einem Batch.
Referenzen
- BatchWriteItem — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Zuletzt verifiziert am 2026-07-28 gegen die oben verlinkte offizielle AWS-Dokumentation.