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 agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。