Python'da DynamoDB Toplu Yazma (boto3 batch_writer)
batch_writer(), Python'ın diğer SDK'lardan daha az iş çıkardığı tek DynamoDB çağrısıdır. Put ve delete işlemlerini tamponlar, onları 25'lik BatchWriteItem isteklerine böler ve işlenmemiş öğeleri kendisi yeniden gönderir. Yapmadığı şey, çoğu toplu yüklemeyi bozan iki başarısızlıktan sizi korumaktır — ve ikisi de bozuk öğeyi veren satırda değil, boşaltma sırasında yüzeye çıkar.
Kod
import boto3
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("Music")
songs = [
{"Artist": "Arturo Sandoval", "SongTitle": "Cubano Chant", "AlbumTitle": "Danzon", "Year": 1994},
{"Artist": "Arturo Sandoval", "SongTitle": "A Mis Abuelos", "AlbumTitle": "Danzon", "Year": 1994},
{"Artist": "Arturo Sandoval", "SongTitle": "Groovin' High", "AlbumTitle": "Swingin'", "Year": 1996},
]
with table.batch_writer() as batch:
for song in songs:
batch.put_item(Item=song)
# batch_writer buffers deletes too — target a key you're NOT also putting
# (two writes to the same key in one batch are rejected as a duplicate)
batch.delete_item(Key={"Artist": "Ella Fitzgerald", "SongTitle": "Misty"})
print(f"Buffered {len(songs)} puts + 1 delete; the batch flushes on exit")Açıklama
- Ertelenmiş boşaltma —
batch.put_item()bir listeye ekleme yapar. Tampon 25'e ulaşana ya dawithbloğu bitene kadar hiçbir şey doğrulanmaz, serileştirilmez ya da gönderilmez; dolayısıyla bozuk bir öğenin traceback'i onu verenput_itemçağrısından değil, boşaltmadan gelir. Bir yineleyiciden yüklüyorsanız, tampona neyin girdiğine dair kendi kaydınızı tutun. - Düz Python değerleri — bu kaynak API'sidir, dolayısıyla
{"N": "1994"}değil1994yazarsınız. Kesirli her şey için Decimal gerekir; birfloattampona kabul edilir ve boşaltmada reddedilir. batch_writer()birTablemetodudur. Okuma tarafındaki karşılığı değildir:batch_get_item,ServiceResource'ta bulunur vetable.batch_get_itemdiye bir şey yoktur. Toplu okumalar için hiç tamponlama, parçalama ya da yeniden deneme yardımcısı yoktur.- Hatalar değil,
UnprocessedItems— ele aldığı tek yeniden deneme budur. Kısıtlanan bir yazma yeniden gönderilir; birValidationExceptionyukarı yayılır. Bunun yerineclient.batch_write_itemüzerinden gitmek, Node.js örneğinde olduğu gibi bütün döngüyü size bırakır. - Hizmet sınırlarını kaldıramaz. İstek başına 25 yazma, öğe başına 400 KB, istek başına 16 MB, koşul yok ve güncelleme yok; her put saklanan öğenin tamamını değiştirir. Bir koruma ya da hep-ya-hiç mi gerekiyor? TransactWriteItems.
batch_writer boşaltmada gerçekte ne yapar
30 put tamponlayın ve yaptığı çağrıları izleyin. table.meta.client.batch_write_item'ı sarmalayıp istek boyutlarını kaydederek, DynamoDB Local 3.3.0'a karşı:
batch sizes sent: [25, 5]İki istek, hizmet sınırında kesilmiş, artanı __exit__ tarafından boşaltılmış. O boşaltma koşulsuzdur: bloğun içinde bir RuntimeError fırlatın, tamponlanan öğeler çıkış yolunda yine de yazılır. Yarı yolda ölen bir toplu yükleme, temiz bir sayfa değil, kısmi bir yükleme bırakır.
Şimdi iki başarısızlık. Aynı anahtarı iki kez tamponlayın — kaynak verinizde bir tekrar olduğu anda olan da budur:
with table.batch_writer() as batch:
batch.put_item(Item={"Artist": "Dup", "SongTitle": "Key", "Year": 1})
batch.put_item(Item={"Artist": "Dup", "SongTitle": "Key", "Year": 2})botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the
BatchWriteItem operation: Provided list of item keys contains duplicatesHiçbir put_item şikâyet etmedi. batch_writer(), siz istemedikçe yinelenenleri ayıklamaz; istemek de table.batch_writer(overwrite_by_pkeys=["Artist", "SongTitle"]) demektir. Aynı iki put'u ondan geçirin, öğe Year: 2 olarak saklanır — tampon anahtar başına son yazmayı tutar; dolayısıyla iki satırınız yanlış kurguladığınız bir anahtar altında farklı öğeler olacaktıysa bu ayıklama sessiz veri kaybıdır.
İkincisi yalnızca boto3'e aittir ve DynamoDB'ye hiç ulaşmaz:
TypeError: Float types are not supported. Use Decimal types instead.4.5'lik bir Rating tamponda şikâyetsiz oturur ve boşaltmada patlar. Decimal("4.5"), {"N": "4.5"} olarak doğru gidip gelir. Bir fiyatı ya da puanı JSON'dan json.loads ile okuyun, her sayı bir float olur; dolayısıyla bu, çoğu içe aktarma betiği için daha ilk çalıştırmada gelen bir başarısızlıktır. json.loads'a parse_float=Decimal geçmek bunu kaynağında düzeltir.
Yerel Python değerleri ile tel biçimi arasında elle gidip geliyorsanız, DynamoDB JSON dönüştürücüsü aynı öğenin her iki tarafını gösterir; böylece Decimal'inizin gerçekte neye dönüştüğünü görebilirsiniz.
Tür eşlemesini kendiniz yazmadan CSV ya da JSON'dan toplu yükleme yapmak için DynoTable'ı indirin.
İlgili örnekler
- Node.js'te DynamoDB BatchWriteItem — batch_writer'ın sakladığı elle yazılan yeniden deneme döngüsü.
- AWS CLI ile DynamoDB BatchWriteItem — kabuktan aynı toplu yazma.
- Python'da DynamoDB PutItem — bunun topladığı tek öğelik yazma.
- 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
- Amazon DynamoDB guide (batch_writer) — Boto3 documentation
- BatchWriteItem — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.