DynamoDB BatchWriteItem in Node.js (AWS SDK v3)

BatchWriteItem scrive o elimina fino a 25 Item in una sola richiesta. Non è un UpdateItem in piccolo: ogni PutRequest sostituisce l'Item memorizzato per intero, e i tipi v3 non ti danno alcun punto in cui agganciare una condizione. Operazioni batch in DynamoDB copre i limiti e il modello di fallimento parziale; questa pagina riguarda la chiamata v3 e l'unico modo in cui perde dati in silenzio.

Codice

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');

Spiegazione

  • Il membro con gli avanzi è UnprocessedItems, non UnprocessedKeys. Il lato lettura usa l'altro nome, e in JavaScript un refuso qui compila, si legge come undefined e trasforma il do/while in una chiamata a passata singola che butta via le scritture sottoposte a throttling. TypeScript lo intercetta; il JS puro no.
  • Non c'è nessun posto dove mettere una condizione. Il tipo WriteRequest di v3 ha esattamente due membri opzionali, PutRequest e DeleteRequest, e nessuno dei due accetta ConditionExpression o ReturnValues. Non è l'SDK che è conservativo: il riferimento dell'API dice che non puoi specificare condizioni sulle singole richieste di put e delete. Se una scrittura ha bisogno di una guardia non appartiene a un batch, appartiene a UpdateItem con una condizione o a una transazione.
  • Due errori intercettabili con catch, entrambi non ripetibili, discriminati su err.name. Ventisei voci sollevano ValidationException / Too many items requested for the BatchWriteItem call. Toccare una chiave due volte solleva Provided list of item keys contains duplicates, e quel messaggio copre anche una coppia put+delete oltre a due put, il che suona strano la prima volta che lo vedi.
  • La lista dei motivi di rifiuto dell'intero batch è più lunga dei tre ovvi. Oltre a più di 25 richieste, un Item da più di 400 KB e un totale sopra i 16 MB, DynamoDB rifiuta il batch per una tabella mancante, una chiave che non corrisponde allo schema, una chiave di partizione oltre 2048 byte o una chiave di ordinamento oltre 1024 byte. Una voce sbagliata ti costa tutte e 25.
  • Il batch ti compra round trip, non capacità. Ogni voce viene fatturata come un singolo PutItem o DeleteItem, arrotondata per eccesso a 1 KB, e un delete puntato su un Item inesistente consuma comunque un'unità di scrittura.

Un PutRequest con la sola chiave distrugge il resto dell'Item

Ella Fitzgerald / Misty parte con un AlbumTitle e un Year. Invia un PutRequest che porta solo i due attributi chiave:

{PutRequest: {Item: {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}}}

Poi rileggilo con ConsistentRead: true. DynamoDB Local 3.3.0 restituisce:

{
  "Artist": { "S": "Ella Fitzgerald" },
  "SongTitle": { "S": "Misty" }
}

AlbumTitle e Year sono spariti. La chiamata è riuscita, UnprocessedItems era {}, e nulla nella risposta menziona i due attributi che ha eliminato. Un put è una sostituzione dell'Item intero, quindi un batch assemblato da un payload parziale (il body di una richiesta API, un sottoinsieme di colonne CSV, un risultato Query proiettato che ha omesso degli attributi) cancella ogni attributo che il payload non portava con sé.

Questa è la modalità di fallimento da mettere in conto quando usi un batch per quello che sembra un aggiornamento. La correzione è leggere prima l'Item corrente e fare il merge, oppure smettere di fare batch e usare UpdateItem, che tocca solo gli attributi che nomini.

L'altro motivo per cui un batch da 25 Item diventa un batch da 12 è la dimensione. Le scritture arrotondano per eccesso a 1 KB ciascuna per la fatturazione e la richiesta si ferma a 16 MB, quindi il conteggio reale dei byte di un Item decide sia la bolletta sia quanti ce ne stanno. Il calcolatore della dimensione degli Item ti dà quel numero per Item prima che tu assembli l'array.

Per caricare, modificare ed eliminare Item in blocco senza scrivere a mano la semantica di sostituzione, scarica DynoTable.

Esempi correlati

Riferimenti

Ultima verifica 2026-07-28 rispetto alla documentazione ufficiale AWS collegata sopra.

Lavora con DynamoDB senza la Console

Un client desktop veloce per DynamoDB che esegue il vero SQL che DynamoDB non può — JOINs, GROUP BY, aggregazioni — con modifica visuale e un agente AI sulle tue chiavi Bedrock.

Prova gratuita di 30 giorni, senza carta di credito — poi il piano Free senza limiti di tempo.