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{}, jadirequest_items = response["UnprocessedKeys"]aman diindeks dan dict kosong yang falsy itulah yang mengakhiriwhile.Responsesjustru yang perlu diwaspadai: tabel yang seluruh key-nya meleset tidak muncul di sana, itulah sebabnya fence tersebut memakai.get("Music", []).ConsistentReaddanProjectionExpressionberada di dalam dict per tabel, bersebelahan dengan"Keys", bukan di sebelahRequestItems. 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 punyabatch_get_itempada ServiceResource, bukan padaTable.boto3.resource("dynamodb").batch_get_item(...)menerima nilai Python native;table.batch_get_itemtidak ada. Asimetri itu mengejutkan orang yang mencarinya setelah memakaitable.batch_writer(), yang memang adalah methodTable. - Backoff hanya berlaku untuk
UnprocessedKeys.ValidationExceptionadalah 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 duplicatesYang 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: # AttributeErrorbotocore 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 helpKasus 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
- DynamoDB BatchGetItem di Node.js — pembacaan batch yang sama dengan AWS SDK v3.
- DynamoDB BatchGetItem dengan AWS CLI — pembacaan batch yang sama dari shell.
- DynamoDB GetItem di Python — pembacaan satu item yang di-batch di sini.
- Operasi batch di DynamoDB — batas, kegagalan parsial, dan kapan batching membuahkan hasil.
- "Too many items requested for the BatchGetItem call" — lebih dari 100 key dalam satu permintaan.
- "Provided list of item keys contains duplicates" — key yang sama dua kali dalam satu batch.
Referensi
- BatchGetItem — Amazon DynamoDB API Reference
- DynamoDB.Client.batch_get_item — Boto3 documentation
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Terakhir diverifikasi 2026-07-28 terhadap dokumentasi resmi AWS yang ditautkan di atas.