Python'da (boto3) DynamoDB PutItem
put_item, bir öğenin tamamını yazar ve aynı birincil anahtara sahip mevcut her öğenin yerini alır (öğe tabanlı eylemler bunun update_item'dan nasıl ayrıldığını ele alıyor). Düşük düzeyli istemcide her öznitelik DynamoDB JSON olarak geçilir ve boto3, hiçbir şey gönderilmeden önce bu biçimi yerel olarak denetler.
Kod
import boto3
from botocore.exceptions import ClientError
client = boto3.client("dynamodb")
try:
client.put_item(
TableName="Music",
Item={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}, "AlbumTitle": {"S": "Danzon"}, "Year": {"N": "1994"}, "Awards": {"N": "0"}},
ConditionExpression="attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)",
ExpressionAttributeNames={"#cond0": "Artist", "#cond1": "SongTitle"},
)
print("Song written")
except ClientError as err:
if err.response["Error"]["Code"] == "ConditionalCheckFailedException":
print("A song with that key already exists — not overwritten")
else:
raiseAçıklama
{"N": 1994} hiçbir zaman AWS'ye ulaşmaz ve except ClientError onu yakalamaz. Botocore isteği önce kendi hizmet modeline karşı doğrular ve N türünün dize beklediği yerdeki bir Python int'i orada başarısız olur:
ParamValidationError: Parameter validation failed:
Invalid type for parameter Item.Year.N, value: 1994, type: <class 'int'>, valid types: <class 'str'>ParamValidationError, ClientError'dan değil BotoCoreError'dan türer; dolayısıyla yukarıdaki parçacıktaki işleyici onu geçirir. Genellikle istediğiniz de budur, çünkü bu bir iş sonucu değil bir hatadır; ama bir yazmanın etrafındaki try/except ClientError'ın her şeyi yakalamadığı anlamına gelir. İyi yanı, hatanın tam yolu, Item.Year.N, adlandırmasıdır; hata ayıklamada bu, sunucu tarafı bir ValidationException'ı yener. Ayrıntı "Parameter validation failed" sayfasında.
Başarısız bir koşulun tüm yüzeyi. Aynı koşullu put'u iki kez yakalayıp istisnadaki her şeyi yazdırmak şunu verdi:
type(e).__name__ ConditionalCheckFailedException
e.response["Error"]["Code"] ConditionalCheckFailedException
e.response["Error"]["Message"] The conditional request failed
e.response["ResponseMetadata"]["HTTPStatusCode"] 400
str(e) An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failedBundan iki şey çıkar. botocore 1.43.58'de nesne modellenmiş bir alt sınıftır, dolayısıyla except client.exceptions.ConditionalCheckFailedException, parçacığın kullandığı err.response["Error"]["Code"] kontrolüyle yan yana çalışır; birini seçin ve tutarlı olun. Ve str(e) hizmetin mesajı değil biçimlendirilmiş bir cümledir, dolayısıyla onu asla bir sabitle karşılaştırmayın.
Başarısız bir koşul yine de bir yazma faturalandırır. AWS: "if the expression evaluates to false, DynamoDB still consumes write capacity units from the table" (2026-07-28 tarihinde alındı). Yalnızca-oluştur yeniden deneme döngüsü, reddedilen her denemenin bedelini öder. Ölçek için: ~15 KB'lık bir öğenin başarılı bir put'u, ReturnConsumedCapacity="TOTAL" altında "CapacityUnits": 15 bildirdi; yazmalar, okumaların kullandığı 4 KB'a değil, 1 KB başına yuvarlanır.
Kaynak API'si farklı bir sözleşmedir ve bunu float ile öğrenirsiniz. boto3.resource("dynamodb").Table("Music").put_item(Item={...}) düz Python alır ve marshalling'i sizin için yapar, ama ikili kayan noktayı doğrudan reddeder:
TypeError: Float types are not supported. Use Decimal types instead.Değeri bir float'tan değil bir dizeden decimal.Decimal("4.5") içine sarın; yoksa hassasiyet kaybı Decimal onu görmeden önce çoktan pişmiş olur. Aynı API üzerinden geri okumak her sayıyı Decimal olarak döndürür; bu bir biçimlendirme ayrıntısı değil, kodunuzda gerçek bir değişikliktir. Bkz. "Float types are not supported".
İki API'yi karıştırmak, hiçbirinin uyarmadığı tuzaktır. Düşük düzeyli istemci, kaynak API'sinin bir float olarak reddedeceği {"N": "1.5"}'i seve seve kabul eder. Biriyle yazıp diğeriyle okuyan bir kod tabanı, girişte hiç Decimal'dan geçmemiş veriden Decimal geri alır.
#cond0 takma adları süs değildir. Bunlar ExpressionAttributeNames üzerinden Artist/SongTitle'a çözümlenir. Satır içi öznitelik adları, biri bir ayrılmış sözcükle çakışana kadar çalışır; sonra ifade, hiç değiştirmediğiniz bir ad yüzünden başarısız olur.
Görsel olarak yapın
Elle yazmanın ilk bozulduğu yer koşul ifadeleridir, çünkü yanlış olanı bir sözdizimi hatası olarak değil reddedilmiş bir yazma olarak başarısız olur. Ücretsiz DynamoDB Expression Builder, ConditionExpression'ı ad ve değer eşlemeleriyle birlikte kurar ve boto3 çağrısını yapıştırmaya hazır olarak üretir.
Kendi tablolarınıza karşı öğe yazmak ve düzenlemek — öznitelik başına bir form, tür seçiciler, sonucu boto3 olarak geri kopyalama — için DynoTable'ı indirin.
İlgili kılavuzlar
- DynamoDB koşul ifadeleri —
attribute_not_exists, iyimser kilitleme ve dahası. - DynamoDB veri türleri — her öznitelik türü DynamoDB JSON'unda nasıl yazılır.
- DynamoDB ConditionalCheckFailedException — öğe zaten varken yalnızca-oluştur koşulunun fırlattığı şey.
- DynamoDB ValidationException — bozuk bir öğe ya da ifade için genel karşılık.
Kaynaklar
- PutItem — Amazon DynamoDB API Reference
- put_item — Boto3 DynamoDB.Client Reference
- Error handling — Boto3 Developer Guide
- Capacity unit consumption — Amazon DynamoDB Developer Guide
- Condition expressions — 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. İstisna metni, yanıt alanları ve kapasite okuması yakalanan çıktıdır, birebir kopyalanmıştır.