Node.js'te DynamoDB BatchWriteItem (AWS SDK v3)
BatchWriteItem, tek bir istekte 25'e kadar öğeyi yazar ya da siler. Daha küçük bir UpdateItem değildir: her PutRequest saklanan öğenin tamamını değiştirir ve v3 türleri size bir koşul iliştirecek hiçbir yer bırakmaz. DynamoDB'de toplu işlemler sınırları ve kısmi başarısızlık modelini ele alır; bu sayfa v3 çağrısı ve onun veriyi sessizce kaybettiği tek yol hakkındadır.
Kod
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');Açıklama
- Artakalan üye
UnprocessedKeysdeğil,UnprocessedItems'dır. Okuma tarafı diğer adı kullanır ve JavaScript'te buradaki bir yazım hatası derlenir,undefinedolarak okunur vedo/while'ı, kısıtlanmış yazmaları yere düşüren tek geçişli bir çağrıya dönüştürür. TypeScript bunu yakalar; düz JS yakalamaz. - Bir koşul koyacak hiçbir yer yoktur. v3
WriteRequesttürünün tam olarak iki isteğe bağlı üyesi vardır —PutRequestveDeleteRequest— ve hiçbiriConditionExpressionya daReturnValueskabul etmez. Bu, SDK'nın tutucu davranması değildir: API başvurusu, tek tek put ve delete isteklerinde koşul belirtemeyeceğinizi söyler. Bir yazmanın korumaya ihtiyacı varsa toplu işlemde işi yoktur; yeri koşullu UpdateItem ya da bir işlemdir. catchedilebilir iki hata, ikisi de yeniden denenemez,err.nameüzerinden ayrıştırılır. Yirmi altı girdiValidationException/Too many items requested for the BatchWriteItem callyükseltir. Tek bir anahtara iki kez dokunmakProvided list of item keys contains duplicatesyükseltir ve o mesaj, iki put kadar bir put+delete çiftini de kapsar — ki ilk gördüğünüzde tuhaf okunur.- Tüm toplu işlemin reddedilme listesi bariz üç maddeden uzundur. 25'ten fazla isteğin, 400 KB'ı aşan bir öğenin ve 16 MB'ı aşan toplamın yanı sıra DynamoDB; olmayan bir tablo, şemayla eşleşmeyen bir anahtar, 2048 baytı aşan bir bölüm anahtarı ya da 1024 baytı aşan bir sıralama anahtarı için de toplu işlemi reddeder. Tek bir kötü girdi size 25'inin hepsine mal olur.
- Toplu işlem gidiş-dönüş satın alır, kapasite değil. Her girdi ayrı bir
PutItemya daDeleteItemolarak, 1 KB'a yukarı yuvarlanarak faturalandırılır ve var olmayan bir öğeye yönelen bir silme yine de bir yazma birimi tüketir.
Yalnızca anahtar içeren bir PutRequest öğenin geri kalanını yok eder
Ella Fitzgerald / Misty başlangıçta bir AlbumTitle ve bir Year taşır. Yalnızca iki anahtar özniteliğini taşıyan tek bir PutRequest gönderin:
{PutRequest: {Item: {Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}}}Sonra onu ConsistentRead: true ile geri okuyun. DynamoDB Local 3.3.0 şunu döndürür:
{
"Artist": { "S": "Ella Fitzgerald" },
"SongTitle": { "S": "Misty" }
}AlbumTitle ve Year gitti. Çağrı başarılı oldu, UnprocessedItems {} idi ve yanıtta düşürdüğü iki öznitelikten söz eden hiçbir şey yok. Bir put, öğenin tamamını değiştirmedir; dolayısıyla kısmi bir yükten (bir API istek gövdesi, bir CSV sütun alt kümesi, öznitelikleri atlayan yansıtılmış bir Query sonucu) kurulmuş bir toplu işlem, yükün taşımadığı her özniteliği siler.
Bir toplu işlemi güncelleme gibi hissettiren bir iş için kullandığınızda hesaba katmanız gereken başarısızlık modu budur. Çözüm, önce mevcut öğeyi okuyup birleştirmek ya da toplu işlemi bırakıp yalnızca adını verdiğiniz özniteliklere dokunan UpdateItem'ı kullanmaktır.
25 öğelik bir toplu işlemin 12 öğelik bir toplu işleme dönüşmesinin diğer nedeni boyuttur. Yazmalar faturalama için her biri 1 KB'a yukarı yuvarlanır ve istek 16 MB'da tavan yapar; dolayısıyla bir öğenin gerçek bayt sayısı hem faturanızı hem de kaçının sığacağını belirler. Öğe boyutu hesaplayıcısı, diziyi kurmadan önce size öğe başına o sayıyı verir.
Değiştirme semantiğini elle yazmadan öğeleri toplu olarak yüklemek, düzenlemek ve silmek için DynoTable'ı indirin.
İlgili örnekler
- Python'da DynamoDB toplu yazma — boto3'ün
batch_writer()'ı yeniden deneme döngüsünü sizin yerinize yapar. - AWS CLI ile DynamoDB BatchWriteItem — kabuktan aynı toplu yazma.
- Node.js'te DynamoDB TransactWriteItems — yazmaların birlikte başarılı ya da başarısız olması gerektiğinde.
- DynamoDB'de toplu işlemler — sınırlar, kısmi başarısızlık ve toplu işlem ne zaman kazandırır.
- "Too many items requested for the BatchWriteItem call" — tek toplu işlemde 25'ten fazla put/delete isteği.
- "Provided list of item keys contains duplicates" — tek toplu işlemde aynı anahtara dokunan iki istek.
Kaynaklar
- 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
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.