Python (boto3) ile DynamoDB Koşullu Yazma
boto3, koşullu bir yazmanın yakalanacak adlandırılmış bir istisna sınıfına sahip olduğu tek SDK'dır ve döndürülen öğenin tahmin edemeyeceğiniz bir yerde saklandığı SDK da odur. İfadenin kendisi her yerde aynı çalışır; DynamoDB koşul ifadeleri işlevleri ve iyimser kilitleme desenini anlatır.
Kod
import boto3
client = boto3.client("dynamodb")
# Update the item only if nobody changed it since we read version 7.
try:
client.update_item(
TableName="Music",
Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
UpdateExpression="SET #upd0 = :updValue0, #version = :newVersion",
ConditionExpression="attribute_exists(#cond0) AND #version = :expectedVersion",
ExpressionAttributeNames={"#upd0": "Genre", "#version": "Version", "#cond0": "Artist"},
ExpressionAttributeValues={
":updValue0": {"S": "Latin Jazz"},
":expectedVersion": {"N": "7"},
":newVersion": {"N": "8"},
},
ReturnValuesOnConditionCheckFailure="ALL_OLD",
)
print("Updated to version 8")
except client.exceptions.ConditionalCheckFailedException as e:
# With ReturnValuesOnConditionCheckFailure="ALL_OLD", the current item
# rides back on the exception — no extra read to see what beat you.
print("Lost the race — item is now:", e.response.get("Item"))Açıklama
ConditionalCheckFailedExceptionmodellenmiş bir sınıftır, dolayısıylaexcept client.exceptions.…çalışır. DynamoDB hatalarının çoğu öyle değildir:ValidationException'ın hiç sınıfı yoktur vee.response["Error"]["Code"]üzerinden eşleştirilmesi gerekir. Modellenmiş sınıf yine deClientError'ın alt sınıfıdır, dolayısıyla üst tarafta geniş birexcept ClientError, işleyicilerinizi dikkatsizce sıralarsanız onu yutar.- Döndürülen öğe,
e.response["Error"]'ın değil,e.response'un üst düzey bir anahtarıdır. Bloğune.response.get("Item")okumasının nedeni budur.["Error"]altında,CodeveMessageyanında aramaya gidip hiçbir şey bulamamak ve parametrenin çalışmadığı sonucuna varmak kolaydır. - Öğe, DynamoDB JSON olarak geri gelir — yerel değerlere alışkın olsanız bile, çünkü bu düşük düzeyli istemcidir. Düz Python isterseniz
boto3.dynamodb.types.TypeDeserializeronu dönüştürür. - Kaynak API aynı korumayı nesnelerle ifade eder:
ConditionExpression=Attr("Version").eq(7) & Attr("Artist").exists(), yerel değerlerle ve yer tutucu haritaları olmadan. Aynı istisnayı fırlatır, dolayısıyla aşağıdaki işleme değişmez. - Başarısız bir denetim yine de bir yazma faturalandırır. Geliştirici Kılavuzu, yanlış bir koşulun yazma kapasitesi tükettiğini ve boyutun eski ve yeni öğenin büyük olanına göre hesaplandığını açıkça belirtir; dolayısıyla çekişmeli bir anahtarda sınırsız bir yeniden deneme, hiç ilerleme kaydetmeden gerçek para harcar.
boto3 döndürülen öğeyi nereye koyar
Bloğu, depolanmış Version değeri 9 olan bir öğeye karşı çalıştırın ve istisnanın yanıt anahtarlarını yazdırın. DynamoDB Local 3.3.0, boto3 1.43.58:
sorted(e.response.keys()) -> ['Error', 'Item', 'ResponseMetadata']
e.response["Item"] -> {'Artist': {'S': 'Arturo Sandoval'},
'Year': {'N': '1994'},
'Version': {'N': '9'},
'SongTitle': {'S': 'Cubano Chant'},
'AlbumTitle': {'S': 'Danzon'}}ReturnValuesOnConditionCheckFailure'ı kaldırın; aynı başarısızlık ['Error', 'ResponseMetadata'] verir. Item anahtarı yoktur ve e.response.get("Item") bir hata fırlatmak yerine None döndürür. Bu hatanın kod incelemesinden sağ çıkan ve üretimde None günlüklemeye başlayan sürümü işte budur.
İfadedeki her ad neden takma adlandırılır
Blok, Version ve Artist yerine #version ve #cond0 yazar; bu, iki sıradan sözcük için aşırıya kaçmış görünür. Bu ikisi için öyledir. Version bir DynamoDB ayrılmış sözcüğü değildir ve çıplak kullanıldığında ad doğrulamasından geçer.
Year ise ayrılmıştır ve aynı tabloda bir tane vardır. Doğrudan onun üzerinde koruma kurarsanız şunu alırsınız:
ValidationException: Invalid ConditionExpression: Attribute name is a reserved keyword;
reserved keyword: YearO listede Name, Status, Size, Count, Data, Owner, Timestamp ve Items dahil 573 sözcük var. Her şeye takma ad vermek, üretilen kodun hangisinin hangisi olduğunu asla bilmek zorunda kalmama yöntemidir. Öznitelik adlarınızı ayrılmış sözcük denetleyicisine yapıştırın; ihtiyaç duyanlar için ExpressionAttributeNames haritasını döndürsün.
Bu korumaları takma adlandırma sizin yerinize halledilmiş hâlde kendi tablolarınıza karşı yazmak için DynoTable'ı indirin.
İlgili örnekler
- Node.js ile DynamoDB koşullu yazma — aynı iyimser kilit, AWS SDK v3 ile.
- AWS CLI ile DynamoDB koşullu yazma — aynı iyimser kilit, kabuktan.
- Python ile DynamoDB PutItem — yalnızca-oluştur
attribute_not_existsput'u. - DynamoDB koşul ifadeleri — desenleriyle birlikte her işlev.
- Birden çok öznitelikte benzersizliği zorunlu kılma — koşullar + işlemler bir arada.
- DynamoDB ConditionalCheckFailedException — başarısız denetim beklendiğinde ve onu ucuza nasıl ele alacağınız.
Kaynaklar
- UpdateItem — Amazon DynamoDB API Reference
- DynamoDB.Client.update_item — Boto3 documentation
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
- Reserved words in DynamoDB — Amazon DynamoDB Developer Guide
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.