Go 中的 DynamoDB GetItem(AWS SDK v2)
在 AWS SDK for Go v2 裡,一筆項目就是一個 map[string]types.AttributeValue,而 types.AttributeValue 是一個封閉介面:唯一的實作就是 SDK 隨附的那十個 AttributeValueMember* 結構。用它們寫出一把鍵很容易。把值讀回來,才是 Go 與其他每一個 SDK 分道揚鑣的地方。
client.GetItem 一樣要完整的主鍵,跟其他地方沒有兩樣。
程式碼
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.GetItem(ctx, &dynamodb.GetItemInput{
TableName: aws.String("Music"),
Key: map[string]types.AttributeValue{
"Artist": &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
"SongTitle": &types.AttributeValueMemberS{Value: "Cubano Chant"},
},
ProjectionExpression: aws.String("#proj0, #proj1, #proj2, #proj3"),
ExpressionAttributeNames: map[string]string{
"#proj0": "Artist",
"#proj1": "SongTitle",
"#proj2": "AlbumTitle",
"#proj3": "Year",
},
})
if err != nil {
log.Fatalf("get item: %v", err)
}
if out.Item == nil {
fmt.Println("Item not found")
return
}
fmt.Println(out.Item)
}說明
- 純量都是指標 —
TableName、ProjectionExpression與ConsistentRead是*string與*bool,好讓 SDK 分得出「未設定」與零值。aws.String、aws.Bool與aws.Int32存在的理由就只有這個。 - 數字讀回來是字串 —
AttributeValueMemberN.Value是string,因為 DynamoDB 在傳輸上就是以字串傳送數字。要讀Year就得寫out.Item["Year"].(*types.AttributeValueMemberN),再接strconv.Atoi。請用 comma-ok 形式的型別斷言;屬性不存在或型別不同時,裸的形式會 panic。 attributevalue.UnmarshalMap才是出路 — 它來自github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue,會把整筆項目映射到帶dynamodbav標籤的結構上,並替你做字串轉數字。只要項目的屬性超過兩三個,就值得直接用它。- 找不到時
out.Item是nil,而err也是nil。如果你不需要區分兩者,len(out.Item) == 0就同時涵蓋了 nil 與空值。 - 用
errors.As比對錯誤 — Go v2 會把服務端錯誤包進 Smithy 的操作錯誤裡,所以err == …與對err.Error()做字串比對都會無聲失敗。請宣告var nf *types.ResourceNotFoundException並把它的位址傳進去。 ConsistentRead: aws.Bool(true)會讓讀取成本加倍,而且在 GSI 上會被拒絕。上面那些#proj別名也不是裝飾用的:Year是保留字,直接在投影中寫出它的名稱會被拒絕。
改用視覺化操作
在 AttributeValueMember* 形式與純 JSON 之間轉譯,在 Go 裡是持續不斷的稅。當你只需要讀或貼一筆項目時,DynamoDB JSON 轉換器會在瀏覽器裡替你完成這趟往返。
DynoTable 則直接把項目顯示成一般的資料列,並把表格背後的查詢匯出成一支建立在同樣這些 SDK v2 型別上的 Go 程式。下載 DynoTable。
相關範例
- Java 中的 DynamoDB GetItem — 以 AWS SDK for Java 2.x 做同一次讀取。
- Go 中的 DynamoDB Query — 讀取整個分割區,而不是單一項目。
- DynamoDB 分割區索引鍵的運作方式 — 為什麼
GetItem需要完整的鍵。 - DynamoDB ResourceNotFoundException — 這裡最常見的第一個錯誤:資料表名稱或區域寫錯。
- 「The provided key element does not match the schema」 — 你傳入的鍵與資料表的鍵結構不符。
參考資料
- GetItem — Amazon DynamoDB API Reference
- Use GetItem 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)
- attributevalue package — AWS SDK for Go v2 (pkg.go.dev)
- Read consistency — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-28,對照上方連結的 AWS 官方文件。