Go中DynamoDB UnmarshalListOfMaps生成空值问题求助
解决DynamoDB反序列化为自定义product类型时出现空/零值的问题
你遇到的情况很典型——明明DynamoDB扫描结果的JSON数据是正确的,但反序列化为自定义product类型时却只得到空/零值。咱们来拆解一下问题根源,然后直接给出解决方案:
问题出在两个关键地方
- 结构体字段的可见性:你定义的
product结构体字段都是小写开头(id、description、price),在Go里这属于私有字段。AWS SDK的反序列化工具(比如dynamodbattribute包)依赖反射来读写字段值,而反射是无法访问私有字段的,所以这些字段根本没法被赋值。 - 缺少DynamoDB序列化标签:DynamoDB返回的JSON是带类型标识的特殊格式(比如
{"N": "0"}表示数字、{"S": "tomato"}表示字符串),你需要给结构体字段加上标签,告诉SDK如何把这些特殊格式映射到你的字段类型上。
修改后的代码实现
首先调整你的product.go结构体定义:
// 注意结构体名和字段名首字母大写,转为公开访问 type Product struct { ID int `dynamodbav:"id"` // 对应DynamoDB里的id属性 Description string `dynamodbav:"description"` // 对应description属性 Price float64 `dynamodbav:"price"` // 对应price属性 }
然后更新查询函数的反序列化逻辑:
import ( "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" ) func listAllProducts() []Product { sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-...")}) if err != nil { // 别忘了添加错误处理逻辑,比如打印日志或者返回错误 log.Printf("Failed to create session: %v", err) return nil } svc := dynamodb.New(sess) // 构造扫描请求,替换成你的表名 scanInput := &dynamodb.ScanInput{ TableName: aws.String("your-product-table"), } scanResult, err := svc.Scan(scanInput) if err != nil { log.Printf("Scan failed: %v", err) return nil } var products []Product // 使用dynamodbattribute包完成反序列化 err = dynamodbattribute.UnmarshalListOfMaps(scanResult.Items, &products) if err != nil { log.Printf("Unmarshal failed: %v", err) return nil } return products }
为什么这样修改有效
- 大写开头的字段变成了公开字段,反射可以正常访问并赋值;
dynamodbav标签指定了结构体字段和DynamoDB属性的对应关系,SDK会自动处理N/S这些类型标识,把字符串形式的数字转换成int、float64类型,把字符串值直接映射到string字段。
这样修改后,你反序列化得到的Product实例就能正确拿到预期的0, tomato, 0.50结果了。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

