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ıyla request_items = response["UnprocessedKeys"] güvenle indekslenebilir ve while'ı sonlandıran şey de falsy olan boş sözlüktür. Dikkat edilmesi gereken Responses'tır: anahtarlarının hepsi ıskalanan bir tablo orada yer almaz; bloğun .get("Music", []) kullanmasının nedeni budur.
  • ConsistentRead ve ProjectionExpression, 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'sinde batch_get_item, Table'da değil ServiceResource'ta bulunur. boto3.resource("dynamodb").batch_get_item(...) yerel Python değerleri alır; table.batch_get_item diye bir şey yoktur. Bu asimetri, table.batch_writer() kullandıktan sonra ona uzananları şaşırtır — çünkü o gerçekten bir Table metodudur.
  • Geri çekilme yalnızca UnprocessedKeys için geçerlidir. Bir ValidationException istekteki 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 duplicates

Birincisi 101 anahtar, ikincisi ise iki kez listelenen aynı anahtardır. Onları yakalamak için yazamayacağınız şeye dikkat edin:

except client.exceptions.ValidationException:  # AttributeError

botocore, 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 help

Gerç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

Kaynaklar

En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.

Console olmadan DynamoDB ile çalış

DynamoDB’nin çalıştıramadığı gerçek SQL’i çalıştıran hızlı bir DynamoDB masaüstü istemcisi — JOINs, GROUP BY, toplamalar — görsel düzenleme ve kendi Bedrock anahtarların üzerinde bir yapay zekâ aracısıyla.

30 günlük ücretsiz deneme, kredi kartı yok — ardından süre sınırı olmayan Ücretsiz plan.