Go'da DynamoDB PutItem (AWS SDK v2)

PutItem bir öğenin tamamını yazar ve aynı birincil anahtara sahip mevcut her öğeyi değiştirir (öğe tabanlı eylemler bunun UpdateItem'dan nasıl farklı olduğunu ele alır). AWS SDK for Go v2'de ilginç kısım çağrının kendisi değil, Go değerlerinizin dışarı çıkarken neye dönüştüğüdür.

Kod

package main

import (
	"context"
	"errors"
	"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)

	_, err = client.PutItem(ctx, &dynamodb.PutItemInput{
		TableName: aws.String("Music"),
		Item: map[string]types.AttributeValue{
			"Artist":     &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
			"SongTitle":  &types.AttributeValueMemberS{Value: "Cubano Chant"},
			"AlbumTitle": &types.AttributeValueMemberS{Value: "Danzon"},
			"Year":       &types.AttributeValueMemberN{Value: "1994"},
			"Awards":     &types.AttributeValueMemberN{Value: "0"},
		},
		ConditionExpression: aws.String("attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)"),
		ExpressionAttributeNames: map[string]string{
			"#cond0": "Artist",
			"#cond1": "SongTitle",
		},
	})
	if err != nil {
		var ccf *types.ConditionalCheckFailedException
		if errors.As(err, &ccf) {
			fmt.Println("A song with that key already exists — not overwritten")
			return
		}
		log.Fatalf("put item: %v", err)
	}
	fmt.Println("Song written")
}

Açıklama

attributevalue.MarshalMap kısayoldur ve fikirleri vardır. Yukarıdaki map[string]types.AttributeValue'yu elle kurmak yerine bir struct'ı github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue'ye vermek olağan hamledir. Bir time.Time, dokunulmamış bir string alanı ve nil bir *int içeren bir struct için gerçekte ürettiği şu:

Artist     => &types.AttributeValueMemberS{Value:"Arturo Sandoval"}
SongTitle  => &types.AttributeValueMemberS{Value:"Cubano Chant"}
Released   => &types.AttributeValueMemberS{Value:"1994-01-01T00:00:00Z"}
Notes      => &types.AttributeValueMemberS{Value:""}
Rating     => &types.AttributeValueMemberNULL{Value:true}

Bundan çıkarılacak üç şey var. time.Time bir Unix sayısına değil, RFC 3339 biçiminde bir dizeye dönüşür; dolayısıyla bir zaman damgası sıralama anahtarı sözlüksel olarak sıralanır ve ancak her değer sıfırla doldurulmuşsa ve aynı saat diliminde ise beklendiği gibi davranır. Dokunulmamış bir dize, dışarıda bırakılmak yerine gerçek bir boş dize özniteliğine dönüşür. Ve nil bir işaretçi NULL'a dönüşür — ki bu var olan bir özniteliktir.

Bir NULL özniteliği attribute_not_exists'i etkisiz kılar. İnsana bir öğleden sonrasına mal olan da budur. Rating'i nil bir *int'ten gelen bir öğe yazın, sonra bir sonraki yazmayı attribute_not_exists(Rating) ile koruyun; başarısız olur:

ConditionalCheckFailedException: The conditional request failed

DynamoDB haklıdır: öznitelik oradadır, NULL tutmaktadır. Çözüm, alanı null yapmak yerine düşüren dynamodbav:"Rating,omitempty" struct etiketidir. Aynı etiket boş dize özniteliğini de engeller — ki bu önemlidir, çünkü onlar seyrek indeksleri bozar ve bir anahtar özniteliğinde doğrudan reddedilir:

ValidationException: One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: Artist

errors.As, asla dize eşleştirme. Go SDK'sı her hizmet hatasını smithy'nin işlem hatasına sarar; dolayısıyla err.Error()'dan aldığınız dize DynamoDB'nin gönderdiği mesaj değildir:

operation error DynamoDB: PutItem, https response error StatusCode: 400, RequestID: 6886fce0-b246-4762-8a8b-0c6dab813040, ConditionalCheckFailedException: The conditional request failed

errors.As(err, &ccf) onu açar ve yukarıda true döndürdü; ccf.ErrorMessage() sonra çıplak The conditional request failed mesajını verir. Dış dize üzerinde bir strings.Contains denetimi bugün çalışır ve SDK sarmalayıcı biçimini değiştirdiği gün bozulur.

Tipli hata sizi engelleyen öğeyi taşıyabilir. Girdide ReturnValuesOnConditionCheckFailure: types.ReturnValuesOnConditionCheckFailureAllOld ayarlayın; ccf.Item dolu olarak geri gelir: yukarıdaki çalıştırmada beş öznitelik, Year dahil, &types.AttributeValueMemberN{Value:"1994"} olarak. Bu, çoğu yeniden deneme döngüsünün elle yaptığı başarısızlık-sonrası-okuma gidiş-dönüşünü ortadan kaldırır. ReturnValues: types.ReturnValueAllOld bunun başarı yolundaki karşılığıdır (ReturnValues).

Sayılar dizedir ve bu bir Go tuhaflığı değildir. AttributeValueMemberN{Value: "1994"} tipli bir dilden gelen herkese yanlış görünür, ama DynamoDB'nin N türü tam da hiçbir şeyin bir float64 üzerinden gidip gelmek zorunda kalmaması için metin olarak taşınan bir ondalıktır. Dönüşüm strconv.FormatInt ve strconv.FormatFloat'tır; attributevalue bunu sizin yerinize yapar.

Ne marshal ederseniz onun bedelini ödersiniz. ~15 KB'lık bir öğenin put'u, ReturnConsumedCapacity ile "CapacityUnits": 15 bildirdi. Yazmalar 1 KB başına yukarı yuvarlanır; dolayısıyla kazara eklenmiş bir blob alanı ya da düşürmek istediğiniz öznitelikleri yayan bir MarshalMap doğrudan faturada görünür.

Görsel olarak yapın

Öğeye gerçekte neyin ineceğine MarshalMap karar verdiğine göre, o öğenin ne kadar ağır olduğunu bilmeye değer. Ücretsiz DynamoDB öğe boyutu hesaplayıcısı, marshal edilmiş JSON'u alır ve bayt boyutunu ve yukarı yuvarlandığı yazma birimlerini döndürür.

Kendi tablolarınıza karşı öğe yazmak ve düzenlemek için — öznitelik başına bir form, tür seçiciler, sonucu Go olarak geri kopyalama — DynoTable'ı indirin.

İlgili örnekler

Kaynaklar

2026-07-28 tarihinde go1.26.5 üzerinde aws-sdk-go-v2/service/dynamodb v1.62.1 ve feature/dynamodb/attributevalue v1.20.55 ile, 9000 numaralı bağlantı noktasındaki DynamoDB Local'e (amazon/dynamodb-local) karşı yeniden üretildi. Marshal edilmiş değerler, hata dizeleri ve kapasite okuması yakalanmış çıktıdır, birebir kopyalanmıştır.

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.