Python'da (boto3) DynamoDB BatchGetItem
batch_get_item, tek istekte birincil anahtara göre 100'e kadar öğe getirir. Aşağıdaki bloktaki while request_items: boto3 deyiminin tamamıdır: DynamoDB artakalanları başarılı bir yanıtta geri verir ve boş bir sözlük falsy'dir, dolayısıyla döngü kendini bitirir. Sınırlar ve kısmi sonuç kuralları DynamoDB'de toplu işlemler sayfasındadır; bu sayfa boto3 çağrısı ve fırlattığı hatalarla ilgilidir.
Kod
import time
import boto3
client = boto3.client("dynamodb")
request_items = {
"Music": {
"Keys": [
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
{"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "A Mis Abuelos"}},
{"Artist": {"S": "Ella Fitzgerald"}, "SongTitle": {"S": "Misty"}},
]
}
}
items = []
attempt = 0
while request_items:
response = client.batch_get_item(RequestItems=request_items)
items.extend(response["Responses"].get("Music", []))
# A partial result is NOT an error: throttling, a >16 MB response, or an
# internal failure returns the leftovers in UnprocessedKeys. Retry them
# with exponential backoff.
request_items = response["UnprocessedKeys"]
if request_items:
attempt += 1
time.sleep(min(0.1 * 2**attempt, 5))
print(f"Fetched {len(items)} items")Açıklama
response["UnprocessedKeys"]her zaman oradadır. Tamamen karşılanmış bir toplu işlemde anahtar vardır ve{}tutar; dolayısıylarequest_items = response["UnprocessedKeys"]güvenle indekslenebilir vewhile'ı sonlandıran şey de falsy olan boş sözlüktür. Dikkat edilmesi gerekenResponses'tır: anahtarlarının hepsi ıskalanan bir tablo orada yer almaz; bloğun.get("Music", [])kullanmasının nedeni budur.ConsistentReadveProjectionExpression, tablo başına sözlüğün içine,RequestItems'ın yanına değil,"Keys"ile yan yana gider. boto3 yanlış yerleştirilmiş bir anahtarı seve seve gönderir ve reddetmeyi hizmete bırakır.- Bu düşük düzeyli istemcidir, dolayısıyla değerler DynamoDB JSON'udur (
{"S": ...},{"N": ...}). Kaynak API'sindebatch_get_item,Table'da değil ServiceResource'ta bulunur.boto3.resource("dynamodb").batch_get_item(...)yerel Python değerleri alır;table.batch_get_itemdiye bir şey yoktur. Bu asimetri,table.batch_writer()kullandıktan sonra ona uzananları şaşırtır — çünkü o gerçekten birTablemetodudur. - Geri çekilme yalnızca
UnprocessedKeysiçin geçerlidir. BirValidationExceptionistekteki bir hatadır ve onu yeniden denemek yalnızca duvar saatini yakar.
Bu çağrının fırlattığı iki hata, birebir
Her ikisi de hiçbir yeniden denemenin düzeltmediği istemci tarafı hatalardır ve her ikisi de düz bir botocore.exceptions.ClientError olarak yüzeye çıkar. DynamoDB Local 3.3.0'a karşı, str(e):
An error occurred (ValidationException) when calling the BatchGetItem operation: Too many items requested for the BatchGetItem call
An error occurred (ValidationException) when calling the BatchGetItem operation: Provided list of item keys contains duplicatesBirincisi 101 anahtar, ikincisi ise iki kez listelenen aynı anahtardır. Onları yakalamak için yazamayacağınız şeye dikkat edin:
except client.exceptions.ValidationException: # AttributeErrorbotocore, DynamoDB istemcisinde 34 adlandırılmış istisna sınıfı modeller ve ValidationException bunlardan biri değildir. ConditionalCheckFailedException ve ProvisionedThroughputExceededException bunlardandır; koşullu yazma sayfasının sınıfa göre yakalayabilmesinin, bu sayfanın ise yakalayamamasının nedeni budur. Modellenmiş bir DuplicateItemException bile vardır ve bir toplu işlemdeki yinelenen anahtarın size verdiği şey o değildir. Dolayısıyla toplu okuma, koda göre dallanmak zorundadır:
except ClientError as e:
if e.response["Error"]["Code"] == "ValidationException":
raise # a bug in the request; retrying will not helpGerçek kodda canınızı yakan yinelenen anahtar durumudur, çünkü bir Query sonucundan ya da bir birleştirme tablosundan derlenen anahtar listesi doğal olarak tekrar eder. Göndermeden önce yinelenenleri ayıklayın; iki sözlüğün ancak her anahtar özniteliği eşleşiyorsa eşit olduğunu unutmayın.
100'lük bir toplu işlemin 100'lük kalmamasının diğer nedeni boyuttur: her öğe faturalama için 4 KB'a yuvarlanır ve yanıt için 16 MB'a karşı sayılır; dolayısıyla 300 KB'lık 100 öğe kabaca 52 tanesi dönerken geri kalanı UnprocessedKeys içinde gelir. Öğe boyutu hesaplayıcısı size çarpacağınız öğe başına değeri verir.
Döngüyü yazmadan önce bir anahtar kümesini geri çekip ne döndüğünü incelemek için DynoTable'ı indirin.
İlgili örnekler
- Node.js'te DynamoDB BatchGetItem — AWS SDK v3 ile aynı toplu okuma.
- AWS CLI ile DynamoDB BatchGetItem — kabuktan aynı toplu okuma.
- Python'da DynamoDB GetItem — bunun topladığı tek öğelik okuma.
- 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 BatchGetItem call" — tek istekte 100'den fazla anahtar.
- "Provided list of item keys contains duplicates" — tek toplu işlemde aynı anahtardan iki tane.
Kaynaklar
- BatchGetItem — Amazon DynamoDB API Reference
- DynamoDB.Client.batch_get_item — Boto3 documentation
- 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ı.