Go'da DynamoDB UpdateItem (AWS SDK v2)
UpdateItem Go'da dolambaçsızdır; tuhaf olan kısım, map[string]types.AttributeValue'nun bir arayüz eşlemesi olmasıdır; dolayısıyla hem gönderdiğiniz değerler hem de geri aldıklarınız dokuz üye struct'tan birine işaretçidir. Tek bir tasarım tercihi aşağıdaki sürtünmenin çoğunu açıklar ve bu parçacıktaki fmt.Println'in öğenizi yazdırmaması gerçeğiyle başlar.
Kod
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
func main() {
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
if err != nil {
log.Fatalf("load config: %v", err)
}
client := dynamodb.NewFromConfig(cfg)
out, err := client.UpdateItem(ctx, &dynamodb.UpdateItemInput{
TableName: aws.String("Music"),
Key: map[string]types.AttributeValue{
"Artist": &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
"SongTitle": &types.AttributeValueMemberS{Value: "Cubano Chant"},
},
UpdateExpression: aws.String("SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2"),
ExpressionAttributeNames: map[string]string{
"#upd0": "Genre",
"#upd1": "Year",
"#upd2": "Awards",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":updValue0": &types.AttributeValueMemberS{Value: "Latin Jazz"},
":updValue1": &types.AttributeValueMemberN{Value: "1994"},
":updValue2": &types.AttributeValueMemberN{Value: "1"},
},
ReturnValues: types.ReturnValueAllNew,
})
if err != nil {
log.Fatalf("update item: %v", err)
}
fmt.Println(out.Attributes) // the item after the update
}Açıklama
AttributeValueMemberN.Valuesayısal bir tür değil, birstring'dir veattributevalue.Marshalonu öyle tutar:int64(9007199254740993)tam olarak"9007199254740993"olarak marshal edilir. DynamoDB sayıları 38 hanelik hassasiyet taşır — herhangi bir Go float'ından fazla; dolayısıyla SDK asla dönüştürmez. Ayrıştırmayı sınırda, bilerek siz yaparsınız.ReturnValues: types.ReturnValueAllNew— sabitin değeri birebir"ALL_NEW"'dir. Belgeler yerine türden okumayı tercih ederseniz,types.ReturnValueAllNew.Values()beşinin hepsini listeler (NONE,ALL_OLD,UPDATED_OLD,ALL_NEW,UPDATED_NEW).UpdateExpressionkendinizin kurduğu bir*string'dir ya da aşağıdakiexpressionpaketine devredersiniz. Her iki durumda da tek ayrıştırıcı DynamoDB'dir:ADD #upd2 :updValue2atomik artırımı verir, birConditionExpressioniçindekiattribute_exists(Artist)çağrıyı bir upsert yerine yalnızca-güncelleme hâline getirir ve yan tümce grameri güncelleme ifadeleri sayfasındadır.ValidationException'ın Go türü yoktur.types/errors.go,ConditionalCheckFailedException,TransactionCanceledException,ProvisionedThroughputExceededExceptionveTransactionConflictExceptiondahil 35 hata struct'ı tanımlar. Doğrulama başarısızlıkları bunların arasında değildir; dolayısıyla kötü bir ifade, yalnızca dizeye bakarak tanıyabileceğiniz genel birsmithy.APIErrorolarak yüzeye çıkar:operation error DynamoDB: UpdateItem, https response error StatusCode: 400, RequestID: 702d67f1-4f15-43dc-b3e9-cea691878801, api error ValidationException: Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: YearAşağıdaki modellenmiş
ConditionalCheckFailedException'ın almadığıapi errorönekine dikkat edin. Varlığı, burada somut bir türe karşıerrors.Askullanmanın size yardımcı olmayacağının iyi bir işaretidir.Buna karşılık başarısız bir koşul gerçek bir türdür.
var ccf *types.ConditionalCheckFailedException; errors.As(err, &ccf)eşleşir ve girdideReturnValuesOnConditionCheckFailure: types.ReturnValuesOnConditionCheckFailureAllOldvarkenccf.Item, öğe gerçekte nasıl olduysa öyle dolu gelir.ccf.ErrorMessage(),err.Error()'ın önüne eklediği taşıma girişi olmadan çıplakThe conditional request failedmesajıdır.
Sonucu geri okumak
Bir arayüz eşlemesi üzerinde fmt.Println(out.Attributes) adresleri yazdırır:
map[Artist:0x1c8cf589e060 Awards:0x1c8cf589e078 Genre:0x1c8cf589e090 SongTitle:0x1c8cf589e0c0 Year:0x1c8cf589e0a8]İki çıkış yolu var. Çoğu kodun yapması gereken şey olan, bir struct'a unmarshal etmek:
var song struct {
Artist string
Genre string
Year int
Awards int
}
err = attributevalue.UnmarshalMap(out.Attributes, &song)
// {Artist:Arturo Sandoval Genre:Latin Jazz Year:1994 Awards:1}Ya da önemsediğiniz tek üyeyi tür doğrulamasıyla almak — ve .Value'nun bir dize olduğunu unutmamak:
n, ok := out.Attributes["Awards"].(*types.AttributeValueMemberN)
if ok {
awards, _ := strconv.Atoi(n.Value) // "1" -> 1
fmt.Println(awards)
}İfadeyi expression paketi yazsın
Go, bu sitede UpdateExpression'ı sizin yerinize üretecek tek SDK'dır. feature/dynamodb/expression yan tümceleri ve her iki eşlemeyi de birlikte kurar:
upd := expression.Set(expression.Name("Genre"), expression.Value("Latin Jazz")).
Set(expression.Name("Year"), expression.Value(1994)).
Add(expression.Name("Awards"), expression.Value(1))
expr, _ := expression.NewBuilder().WithUpdate(upd).Build()Çıkan şey yazdığınız şey değildir:
UpdateExpression: ADD #0 :0
SET #1 = :1, #2 = :2
Names: map[#0:Awards #1:Genre #2:Year]Kurucu yan tümceleri yeniden sıraladı, aralarına bir satır sonu koydu ve yer tutucuları kendisi numaralandırdı; dolayısıyla #0, andığınız ilk ad değil Awards'tır. Aşağı akışta hiçbir şey bunu önemsemez, ama dizeler düzenlemeler arasında kararlı değildir — bu da onları testlerde doğrulanacak kötü bir şey yapar. expr.Update(), expr.Names() ve expr.Values()'i doğrudan UpdateItemInput'a geçirin ve onlara hiç bakmayın.
İyi yanı, her ada takma ad vermesidir; böylece ayrılmış sözcükler artık sahaya sürebileceğiniz bir hata sınıfı olmaktan çıkar. İfadeyi bunun yerine elle yazıyorsanız, öznitelik adlarını önce DynamoDB ayrılmış sözcük denetleyicisinden geçirin — AWS listesinde 573 girdi var ve Year, Name ile Status hepsi listede. Ve bir öğeye arayüz işaretçilerinden oluşan bir eşleme olarak değil de veri olarak bakmayı tercih ederseniz, DynoTable'ı indirin.
İlgili örnekler
- Java'da DynamoDB UpdateItem — AWS SDK for Java 2.x ile aynı güncelleme.
- Go'da DynamoDB PutItem — bunun yerine öğenin tamamını değiştirin.
- DynamoDB güncelleme ifadeleri —
SET,ADD,REMOVE,DELETEve idiyomlar. - ReturnValues'ı anlamak — her
ReturnValuesseçeneğinin size ne verdiği. - "Attribute name is a reserved keyword" — buradaki takma ad eşlemesi neden isteğe bağlı değil.
- "Invalid UpdateExpression" söz dizimi hataları — yaygın SET/ADD söz dizimi hataları, çözülmüş hâliyle.
Kaynaklar
- UpdateItem — Amazon DynamoDB API Reference
- Use UpdateItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- dynamodb package — AWS SDK for Go v2 (pkg.go.dev)
- dynamodb/types package — AWS SDK for Go v2 (pkg.go.dev)
- expression package — AWS SDK for Go v2 (pkg.go.dev)
- Update expressions — Amazon DynamoDB Developer Guide
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.