DynamoDB PutItem di Go (AWS SDK v2)
PutItem menulis satu item utuh dan mengganti item mana pun yang punya primary key sama (aksi berbasis item membahas bedanya dengan UpdateItem). Di AWS SDK for Go v2, bagian menariknya bukan panggilannya, melainkan menjadi apa nilai-nilai Go Anda dalam perjalanan keluar.
Kode
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")
}Penjelasan
attributevalue.MarshalMap adalah jalan pintasnya, dan ia punya pendirian. Menyuapkan sebuah struct ke github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue alih-alih membangun sendiri map[string]types.AttributeValue di atas adalah langkah yang lazim. Inilah yang benar-benar ia hasilkan untuk sebuah struct berisi time.Time, field string yang tak disentuh, dan *int bernilai nil:
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}Ada tiga hal yang bisa dipetik dari situ. time.Time menjadi string RFC 3339, bukan angka Unix, jadi sort key berupa timestamp diurutkan secara leksikografis dan hanya akan berperilaku benar kalau setiap nilai diberi padding nol dan berada di zona yang sama. String yang tak disentuh menjadi atribut string kosong sungguhan alih-alih ditinggalkan. Dan pointer nil menjadi NULL, yaitu atribut yang ada.
Atribut NULL mengalahkan attribute_not_exists. Yang satu ini bisa menghabiskan satu sore. Tulis item yang Rating-nya berasal dari *int bernilai nil, lalu jaga penulisan berikutnya dengan attribute_not_exists(Rating) dan ia gagal:
ConditionalCheckFailedException: The conditional request failedDynamoDB benar: atributnya ada, berisi NULL. Perbaikannya adalah tag struct dynamodbav:"Rating,omitempty", yang membuang field itu alih-alih menge-null-kannya. Tag yang sama juga mencegah atribut string kosong, yang penting karena hal itu merusak sparse index dan, pada atribut key, ditolak mentah-mentah:
ValidationException: One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: ArtistPakai errors.As, jangan sekali-kali mencocokkan string. SDK Go membungkus setiap error layanan dalam operation error milik smithy, jadi string yang Anda dapat dari err.Error() bukanlah pesan yang dikirim DynamoDB:
operation error DynamoDB: PutItem, https response error StatusCode: 400, RequestID: 6886fce0-b246-4762-8a8b-0c6dab813040, ConditionalCheckFailedException: The conditional request failederrors.As(err, &ccf) membukanya dan mengembalikan true di atas; ccf.ErrorMessage() lalu memberikan The conditional request failed yang polos. Pemeriksaan strings.Contains pada string terluar berhasil hari ini dan rusak pada hari SDK mengubah format pembungkusnya.
Error bertipe bisa membawa item yang menghalangi Anda. Setel ReturnValuesOnConditionCheckFailure: types.ReturnValuesOnConditionCheckFailureAllOld pada input dan ccf.Item kembali terisi: lima atribut pada jalan di atas, termasuk Year sebagai &types.AttributeValueMemberN{Value:"1994"}. Itu menghemat round trip baca-setelah-gagal yang dilakukan sendiri oleh kebanyakan loop retry. ReturnValues: types.ReturnValueAllOld adalah padanannya di jalur sukses (ReturnValues).
Angka adalah string, dan itu bukan keanehan Go. AttributeValueMemberN{Value: "1994"} terlihat salah bagi siapa pun yang datang dari bahasa bertipe, tetapi tipe N DynamoDB adalah desimal yang diangkut sebagai teks justru supaya tak ada yang harus melewati float64 pulang-pergi. strconv.FormatInt dan strconv.FormatFloat adalah konversinya; attributevalue melakukannya untuk Anda.
Apa yang Anda marshal itulah yang Anda bayar. Sebuah put atas item ~15 KB melaporkan "CapacityUnits": 15 dengan ReturnConsumedCapacity. Penulisan dibulatkan ke atas per 1 KB, jadi field blob yang tak sengaja ikut, atau MarshalMap yang memancarkan atribut yang niatnya Anda buang, langsung muncul di tagihan.
Lakukan secara visual
Karena MarshalMap yang menentukan apa yang benar-benar mendarat di item, ada baiknya tahu berapa berat item itu. Kalkulator ukuran item DynamoDB gratis menerima JSON hasil marshalling lalu mengembalikan ukuran byte dan write unit hasil pembulatannya.
Untuk menulis dan menyunting item terhadap tabel Anda sendiri — satu form per atribut, pemilih tipe, dan menyalin hasilnya kembali sebagai Go — unduh DynoTable.
Contoh terkait
- DynamoDB PutItem di Java — penulisan bersyarat yang sama dengan AWS SDK for Java 2.x, di mana nilai yang tak disetel gagal dengan cara sebaliknya.
- DynamoDB UpdateItem di Go — mengubah atribut tertentu alih-alih mengganti itemnya.
- Condition expression DynamoDB —
attribute_not_exists, optimistic locking, dan lainnya. - DynamoDB ConditionalCheckFailedException — apa yang dilempar kondisi hanya-buat ketika itemnya sudah ada.
- DynamoDB ValidationException — penampung serba guna untuk item atau expression yang cacat.
Referensi
- PutItem — Amazon DynamoDB API Reference
- Use PutItem with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- dynamodb package — AWS SDK for Go v2 (pkg.go.dev)
- attributevalue package — AWS SDK for Go v2 (pkg.go.dev)
- Handling errors — AWS SDK for Go v2 Developer Guide
- Condition expressions — Amazon DynamoDB Developer Guide
Direproduksi 2026-07-28 pada go1.26.5 dengan aws-sdk-go-v2/service/dynamodb v1.62.1 dan feature/dynamodb/attributevalue v1.20.55, terhadap DynamoDB Local (amazon/dynamodb-local) pada port 9000. Nilai hasil marshalling, string error, dan pembacaan kapasitas di atas adalah keluaran yang ditangkap, dikutip apa adanya.