Python'da (boto3) DynamoDB GetItem
get_item, tek bir öğeyi tam birincil anahtarına göre getirir. boto3'ün düşük düzeyli istemcisi (boto3.client("dynamodb")) her iki yönde de DynamoDB JSON konuşur; dolayısıyla anahtar türüyle sarmalanmış olarak gider ve öğe de aynı şekilde geri gelir. query ve scan'den nasıl ayrıldığı öğe tabanlı eylemler sayfasında ele alınıyor.
Kod
import boto3
client = boto3.client("dynamodb")
response = client.get_item(
TableName="Music",
Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
ProjectionExpression="#proj0, #proj1, #proj2, #proj3",
ExpressionAttributeNames={"#proj0": "Artist", "#proj1": "SongTitle", "#proj2": "AlbumTitle", "#proj3": "Year"},
)
item = response.get("Item")
if item is None:
print("Item not found")
else:
print(item)Açıklama
Bir ıska, içinde hiç Item anahtarı olmayan bir yanıt döndürür. None değil, boş bir sözlük de değil. Aynı tabloyu var olmayan bir anahtar için okuduğunuzda, yanıtın en üst düzey anahtarları tam olarak şunlardı:
['ResponseMetadata']Parçacığın response.get("Item") kullanmasının nedeni budur. response["Item"], sıradan bulunamadı yolunda KeyError fırlatır; eksik bir satır bir web işleyicisinde işte böyle 500'e dönüşür. Okuma için yine de faturalandırılırsınız: AWS'nin okuma kapasitesi sayfası, "if you perform a read operation on an item that doesn't exist, DynamoDB will still consume read throughput as outlined above" diyor (2026-07-28 tarihinde alındı).
Year ayrılmış bir sözcüktür; üretilen parçacığın yansıtılan her özniteliğe takma ad vermesinin nedeni budur. #proj takma adlarını atın ve ProjectionExpression="Year" geçin; motor okumayı reddeder:
ValidationException: Invalid ProjectionExpression: Attribute name is a reserved keyword; reserved keyword: YearKoşulsuz takma ad vermenin hiçbir bedeli yoktur ve bu başarısızlık sınıfının tamamını ortadan kaldırır. Tam liste 573 sözcük uzunluğundadır; bkz. "Attribute name is a reserved keyword".
Key'i yanlış yapmanın dört yolu, üç farklı mesaj. Bunları birbirinden ayırt etmekte fayda var, çünkü hiçbiri insanların beklediği "provided key element does not match the schema" hatası değil. Artist (bölüm) + SongTitle (sıralama) ile anahtarlanmış bir Music tablosuna karşı yeniden üretildi:
| Ne geçtiniz | Birebir ValidationException mesajı |
|---|---|
{"Artist": …} — sıralama anahtarı eksik | The number of conditions on the keys is invalid |
{"Artist": …, "SongTitle": …, "Extra": …} | The number of conditions on the keys is invalid |
{"Artist": …, "Song": …} — yanlış öznitelik adı | One of the required keys was not given a value |
{"Artist": {"N": "1"}, …} — yanlış tür | One or more parameter values were invalid: Type mismatch for key |
Eksik bir anahtar özniteliğinin ve fazladan bir tanesinin aynı mesajı ürettiğine dikkat edin; yani "number of conditions" ifadesi "çok az geçtiniz" değil, "bana tam olarak anahtar şemasını vermediniz" demektir.
ProjectionExpression yükü kırpar, faturayı değil. ~15 KB'lık bir öğe ReturnConsumedCapacity="TOTAL" ile üç şekilde okundu:
full item, eventually consistent CapacityUnits: 2.0
ProjectionExpression="#y" (Year only) CapacityUnits: 2.0
ProjectionExpression="#y" + ConsistentRead CapacityUnits: 4.0Yansıtma, yanıtı ~15 KB'tan tek bir sayıya indirdi ve maliyeti hiç değiştirmedi. AWS bunu açıkça söylüyor: "The number of capacity units consumed will be the same whether you request all of the attributes (the default behavior) or just some of them (using a projection expression)" (Query API Reference, 2026-07-28 tarihinde alındı). O listede sayıyı oynatan tek bayrak ConsistentRead=True'dur ve onu ikiye katlar. Yansıtmaların gerçekte ne işe yaradığı için yansıtma ifadeleri sayfasına bakın.
Kaynak API'si daha hoş bir yazım değil, farklı bir sözleşmedir. boto3.resource("dynamodb").Table("Music").get_item(...) düz Python ve her sayıyı decimal.Decimal olarak döndürür:
{'Artist': 'Arturo Sandoval', 'AlbumTitle': 'Danzon', 'Awards': Decimal('0'), 'Year': Decimal('1994'), 'SongTitle': 'Cubano Chant'}Bu iki tarafı da keser. Aynı API üzerinden bir float ile geri yazmak, istek makinenizden çıkmadan önce hata fırlatır:
TypeError: Float types are not supported. Use Decimal types instead.Bu sizi ısırırsa, "Float types are not supported" sayfasında çözümü var. Asıl tuzak, iki API'yi tek bir kod tabanında karıştırmaktır: düşük düzeyli istemci, kaynak API'sinin reddedeceği {"N": "1.5"}'i seve seve kabul eder.
Hatalar botocore istisnaları olarak gelir ve boto3 onlara gerçek sınıflar verir. 1.43.58'de başarısız bir koşul için fırlatılan nesne, bir ClientError alt sınıfı olan ConditionalCheckFailedException'dır; dolayısıyla hem except ClientError artı bir err.response["Error"]["Code"] kontrolü hem de except client.exceptions.ConditionalCheckFailedException işe yarar. Kod tabanınızın zaten kullandığı hangisiyse onu tercih edin; str(e) üzerinden eşleştirmeyin.
Görsel olarak yapın
Elle takma ad vermeden önce: ücretsiz DynamoDB ayrılmış sözcük denetleyicisi öznitelik adlarınızı alır, 573 ayrılmış sözcükten hangilerine çarptığınızı söyler ve yapıştırmaya hazır ExpressionAttributeNames eşlemesini üretir.
Tablolara göz atmak ve kendi verinize karşı GetItem çalıştırmak — anahtar biçimi, sonuç ızgarası, isteği boto3 olarak geri kopyalama — için DynoTable'ı indirin.
İlgili kılavuzlar
- Query ile Scan karşılaştırması — tek bir
get_itembirquery'yi ne zaman yener. - DynamoDB veri türleri — her öznitelik türü DynamoDB JSON'unda nasıl temsil edilir.
- DynamoDB ResourceNotFoundException — buradaki alışılmış ilk hata: yanlış tablo adı ya da bölge.
- "The provided key element does not match the schema" — geçtiğiniz anahtar tablonun anahtar şemasıyla eşleşmiyor.
Kaynaklar
- GetItem — Amazon DynamoDB API Reference
- get_item — Boto3 DynamoDB.Client Reference
- Read consistency — Amazon DynamoDB Developer Guide
- Capacity unit consumption — Amazon DynamoDB Developer Guide
2026-07-28 tarihinde boto3 1.43.58 / botocore 1.43.58 ile 9000 numaralı bağlantı noktasındaki DynamoDB Local'a (amazon/dynamodb-local) karşı yeniden üretildi. Yukarıdaki her mesaj ve kapasite değeri motor çıktısıdır, birebir kopyalanmıştır. DynamoDB Local hizmetin kendisi değildir; ikisinin bir hatayı farklı ifade ettiği bilinen yerlerde bunu hata sayfasında belirtiyoruz.