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)
}

說明

  • 純量都是指標TableNameProjectionExpressionConsistentRead*string*bool,好讓 SDK 分得出「未設定」與零值。aws.Stringaws.Boolaws.Int32 存在的理由就只有這個。
  • 數字讀回來是字串AttributeValueMemberN.Valuestring,因為 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.Itemnil,而 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

相關範例

參考資料

最後驗證於 2026-07-28,對照上方連結的 AWS 官方文件。

不必透過主控台就能操作 DynamoDB

一款快速的 DynamoDB 桌面用戶端,可執行 DynamoDB 無法執行的真正 SQL — JOINs、GROUP BY、聚合 — 並支援視覺化編輯與使用你自己的 Bedrock 金鑰的 AI 代理。

30 天免費試用,無需信用卡 — 之後為無時間限制的免費方案。