AWS CLI ile DynamoDB Koşullu Yazma
Koşullu bir yazmayı kabuktan göndermek kolaydır, okumak ise gariptir; çünkü başarısız olanın ilginç sonucu çıktı olarak değil, hata olarak gelir. DynamoDB koşul ifadeleri, ifadenin neler söyleyebileceğini anlatır; bu sayfa ise onu CLI'dan çalıştırmak ve kaybeden öğeyi başarısızlığın içinden geri çıkarmakla ilgilidir.
Kod
aws dynamodb update-item \
--table-name 'Music' \
--key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
--update-expression 'SET #upd0 = :updValue0, #version = :newVersion' \
--condition-expression 'attribute_exists(#cond0) AND #version = :expectedVersion' \
--expression-attribute-names '{"#upd0":"Genre","#version":"Version","#cond0":"Artist"}' \
--expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":expectedVersion":{"N":"7"},":newVersion":{"N":"8"}}'Başarılı olduğunda komut hiçbir şey yazdırmaz ve 0 ile çıkar. Başka bir yazıcı oraya önce ulaştıysa koşul başarısız olur ve CLI, hizmetin mesajını bildirir:
An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failedAçıklama
- Başarı sessizdir. Çıktı yok, çıkış kodu 0. Ayrıştıracak ve üzerinde doğrulama yapacak bir şey yoktur, dolayısıyla bir kabuk betiği çıkış durumunu sonuç olarak ele almak zorundadır. Güncellenmiş öğenin yazdırılmasını istiyorsanız
--return-values ALL_NEWekleyin. - Başarısızlık, çıkış durumu 254'tür, ki bu CLI v2'nin istemci tarafı hata kodudur ve hatalı biçimlendirilmiş bir istekle paylaşılır. Yeniden denemeden önce mesaja göre dallanın; yoksa ifadenizdeki bir yazım hatası sonsuz bir geri çekilme döngüsüne dönüşür.
--return-values-on-condition-check-failure ALL_OLDburada gerçekten çalışır. Geçerli değerlerALL_OLDveNONE'dır ve okuma kapasitesi tüketmez. Öğeyi hatanın içinden çıkarmak bir bayrak daha gerektirir; aşağıda anlatılıyor.- Koşul ve güncelleme, ad alanını paylaşan ayrı bayraklardır.
--expression-attribute-namesve--expression-attribute-values,--update-expressionile--condition-expressionarasında birleştirilir; üretilen adların her yan tümcede yeniden başlamak yerine#upd0,#cond0diye ilerlemesinin nedeni budur. Aynı yer tutucuyu iki farklı anlam için yeniden kullanırsanız ikincisi sessizce kazanır. - Başarısız bir yazma yine de faturalandırılır. Geliştirici Kılavuzu açıktır: yanlış olarak değerlendirilen bir koşul yine de yazma kapasitesi tüketir ve boyut, eski ve yeni öğenin büyük olanına göre hesaplanır. Koşullar ucuz bir varlık yoklaması değildir.
Başarısızlık çıktısı ve öğeyi ondan nasıl çıkarırsınız
Yukarıdaki bloğu bir kez çalıştırın, sessizce başarılı olur. Version artık 7 değilken ikinci kez çalıştırın; aws-cli/2.36.9 stderr'e şunu yazdırır:
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed--return-values-on-condition-check-failure ALL_OLD ekleyin; varsayılan çıktı, size dahası olduğunu gösterecektir ama göstermeden:
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed
Additional error details:
Item: <complex value>
Use "--cli-error-format json" or another error format to see the full details.<complex value>, varsayılan metin işleyicisinin sakladığı öğedir. --cli-error-format json ekleyin ve her şey yazdırılsın:
{
"Message": "The conditional request failed",
"Code": "ConditionalCheckFailedException",
"Item": {
"Artist": {"S": "Arturo Sandoval"},
"Year": {"N": "1994"},
"Version": {"N": "8"},
"SongTitle": {"S": "Cubano Chant"},
"AlbumTitle": {"S": "Danzon"},
"Genre": {"S": "Latin Jazz"}
}
}(Öznitelik haritaları her biri tek satıra katlandı; geri kalan her şey yazdırıldığı gibidir.) İlk çalıştırma başarılı olduğu için Version 8 ve Genre ayarlanmış durumda. Bir kabuk betiğinden kapatılmış iyimser kilitleme döngüsü işte budur: stderr'i jq -r '.Item.Version.N' içinden geçirin, sonucu :expectedVersion olarak geri besleyin, yeniden deneyin. Ne get-item gerekir ne de okuma ile yeniden deneme arasında üçüncü bir yazıcının araya girebileceği bir pencere kalır.
Yeniden denemeler bedava değildir. Reddedilen her deneme bir yazma birimi tüketir, dolayısıyla sıkı bir döngü altındaki çekişmeli bir anahtar, hiç ilerleme kaydetmeden düzenli olarak fatura üretir. Denemeleri sınırlamadan önce bir yeniden deneme fırtınasının gerçekte neye mal olduğunu bilmek isterseniz, fiyatlandırma hesaplayıcısı bir yazma hızını aylık bir rakama çevirir.
Bu korumaları yer tutucu haritalarını kabukta tırnaklamadan kendi tablolarınıza karşı çalıştırmak için DynoTable'ı indirin.
İlgili örnekler
- Node.js ile DynamoDB koşullu yazma — aynı iyimser kilit, AWS SDK v3 ile.
- Python ile DynamoDB koşullu yazma — aynı iyimser kilit, boto3 ile.
- AWS CLI ile DynamoDB PutItem — yalnızca-oluştur
attribute_not_existsput'u. - DynamoDB koşul ifadeleri — desenleriyle birlikte her işlev.
- ReturnValues'ı anlamak — her dönüş seçeneğinin size ne verdiği.
- DynamoDB ConditionalCheckFailedException — başarısız denetim beklendiğinde ve onu ucuza nasıl ele alacağınız.
Kaynaklar
- UpdateItem — Amazon DynamoDB API Reference
- update-item — AWS CLI Command Reference
- Condition expressions — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.