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: Year

Koş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çtinizBirebir ValidationException mesajı
{"Artist": …} — sıralama anahtarı eksikThe 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ürOne 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.0

Yansı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

Kaynaklar

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.

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.