DynamoDB BatchGetItem di Python (boto3)

batch_get_item mengambil hingga 100 item berdasarkan primary key dalam satu permintaan. while request_items: pada fence di bawah adalah keseluruhan idiom boto3: DynamoDB mengembalikan sisanya pada respons yang berhasil, dan dict kosong bersifat falsy, jadi loop itu mengakhiri dirinya sendiri. Batas dan aturan hasil parsialnya ada di operasi batch di DynamoDB; halaman ini membahas panggilan boto3-nya dan error yang dilemparkannya.

Kode

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")

Penjelasan

  • response["UnprocessedKeys"] selalu ada. Pada batch yang terlayani penuh, key itu tetap ada dan berisi {}, jadi request_items = response["UnprocessedKeys"] aman diindeks dan dict kosong yang falsy itulah yang mengakhiri while. Responses justru yang perlu diwaspadai: tabel yang seluruh key-nya meleset tidak muncul di sana, itulah sebabnya fence tersebut memakai .get("Music", []).
  • ConsistentRead dan ProjectionExpression berada di dalam dict per tabel, bersebelahan dengan "Keys", bukan di sebelah RequestItems. boto3 dengan senang hati mengirim key yang salah tempat dan membiarkan layanan menolaknya.
  • Ini adalah client tingkat rendah, jadi nilainya berupa DynamoDB JSON ({"S": ...}, {"N": ...}). API resource punya batch_get_item pada ServiceResource, bukan pada Table. boto3.resource("dynamodb").batch_get_item(...) menerima nilai Python native; table.batch_get_item tidak ada. Asimetri itu mengejutkan orang yang mencarinya setelah memakai table.batch_writer(), yang memang adalah method Table.
  • Backoff hanya berlaku untuk UnprocessedKeys. ValidationException adalah bug dalam permintaan, dan mencobanya ulang cuma membakar waktu.

Dua error yang dilemparkan panggilan ini, apa adanya

Keduanya adalah kesalahan di sisi klien yang tak bisa diperbaiki percobaan ulang, dan keduanya muncul sebagai botocore.exceptions.ClientError biasa. Terhadap DynamoDB Local 3.3.0, 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

Yang pertama adalah 101 key, yang kedua adalah key yang sama didaftarkan dua kali. Perhatikan apa yang tidak bisa Anda tulis untuk menangkapnya:

except client.exceptions.ValidationException:  # AttributeError

botocore memodelkan 34 kelas exception bernama pada client DynamoDB, dan ValidationException bukan salah satunya. ConditionalCheckFailedException dan ProvisionedThroughputExceededException termasuk, itulah sebabnya halaman penulisan bersyarat bisa menangkap berdasarkan kelas sementara halaman ini tidak. Bahkan ada DuplicateItemException yang dimodelkan, dan itu bukan yang Anda dapatkan dari key duplikat dalam sebuah batch. Jadi pembacaan batch harus bercabang berdasarkan kode:

except ClientError as e:
    if e.response["Error"]["Code"] == "ValidationException":
        raise  # a bug in the request; retrying will not help

Kasus key duplikat itulah yang menggigit di kode nyata, karena daftar key yang dirakit dari hasil Query atau tabel penghubung secara alami mengulang. Deduplikasikan sebelum mengirim, dan ingat bahwa dua dict hanya setara jika setiap atribut key cocok.

Ukuran adalah alasan lain mengapa batch berisi 100 tidak bertahan sebagai batch berisi 100: setiap item dibulatkan ke atas ke 4 KB untuk penagihan dan dihitung terhadap 16 MB untuk responsnya, jadi 100 item berukuran 300 KB kembali kira-kira 52 saja dengan sisanya di UnprocessedKeys. Kalkulator ukuran item memberi Anda angka per item untuk dikalikan.

Untuk menarik kembali sekumpulan key dan memeriksa apa yang dikembalikan sebelum menulis loop-nya, unduh DynoTable.

Contoh terkait

Referensi

Terakhir diverifikasi 2026-07-28 terhadap dokumentasi resmi AWS yang ditautkan di atas.

Bekerja dengan DynamoDB tanpa Console

Klien desktop DynamoDB yang cepat dan menjalankan SQL sungguhan yang tidak bisa dijalankan DynamoDB — JOINs, GROUP BY, agregasi — dengan editing visual dan agen AI pada kunci Bedrock milik Anda sendiri.

Uji coba gratis 30 hari, tanpa kartu kredit — lalu paket Free tanpa batas waktu.