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, nicht UnprocessedKeys. Die Leseseite nutzt den anderen Namen, und in JavaScript kompiliert ein Tippfehler hier, liest sich als undefined und macht aus dem do/while einen 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, PutRequest und DeleteRequest, und keiner nimmt ConditionExpression oder ReturnValues an. 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 catch abfangbare Fehler, beide nicht wiederholbar, unterschieden über err.name. Sechsundzwanzig Einträge lösen ValidationException / Too many items requested for the BatchWriteItem call aus. Denselben Key zweimal anzufassen löst Provided list of item keys contains duplicates aus, 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 PutItem oder DeleteItem abgerechnet, 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

Referenzen

Zuletzt verifiziert am 2026-07-28 gegen die oben verlinkte offizielle AWS-Dokumentation.

Mit DynamoDB ohne die Console arbeiten

Ein schneller DynamoDB-Desktop-Client, der das echte SQL ausführt, das DynamoDB nicht kann — JOINs, GROUP BY, Aggregationen — mit visueller Bearbeitung und einem KI-Agenten auf deinen eigenen Bedrock-Schlüsseln.

30 Tage kostenlos testen, keine Kreditkarte — danach der Kostenlos-Tarif ohne Zeitlimit.