Golang操作DynamoDB遇ValidationException:键元素与Schema不匹配
问题原因
你的Movie结构体通过json标签定义了与DynamoDB属性的映射关系,但这里存在字段名匹配错误:
- 结构体的
Key字段被json:"userId"标签映射为DynamoDB中的userId属性 - 结构体的
Onboarding字段被json:"username"标签映射为DynamoDB中的username属性
而你明确表示表的Partition Key是Key、Sort Key是Onboarding,这就导致dynamodbattribute.MarshalMap生成的键(userId和username)与表的主键字段名完全不匹配,触发了ValidationException错误。
至于插入操作成功,大概率是插入时的逻辑没有依赖这个结构体的映射(比如手动构造了符合表主键的字段),或者你误将表的主键定义成了userId和username但自己没意识到。
解决方法
方法1:添加dynamodb标签指定映射关系
dynamodbattribute包优先读取dynamodb标签来确定属性名,修改结构体为表的主键字段名指定对应标签:
type Movie struct { Year int `json:"year" dynamodb:"year"` Title string `json:"title" dynamodb:"title"` Key string `json:"userId" dynamodb:"Key"` // 对应表的Partition Key Email string `json:"email" dynamodb:"email"` Bio string `json:"bio" dynamodb:"bio"` Number int `json:"phoneNumber" dynamodb:"phoneNumber"` SocialHandle string `json:"socialHandle" dynamodb:"socialHandle"` Onboarding string `json:"username" dynamodb:"Onboarding"` // 对应表的Sort Key BankDetails string `json:"bankDetails" dynamodb:"bankDetails"` Image string `json:"image" dynamodb:"image"` Password string `json:"password" dynamodb:"password"` Resume string `json:"resume" dynamodb:"resume"` Pincode string `json:"pinCode" dynamodb:"pinCode"` }
修改后MarshalMap会生成包含Key和Onboarding的键,与表的schema完全匹配。
方法2:修改json标签匹配表主键
如果不需要兼顾JSON序列化的字段名,可以直接把Key和Onboarding的json标签改成表的主键字段名:
type Movie struct { Year int `json:"year"` Title string `json:"title"` Key string `json:"Key"` // 直接映射表的Partition Key Email string `json:"email"` Bio string `json:"bio"` Number int `json:"phoneNumber"` SocialHandle string `json:"socialHandle"` Onboarding string `json:"Onboarding"` // 直接映射表的Sort Key BankDetails string `json:"bankDetails"` Image string `json:"image"` Password string `json:"password"` Resume string `json:"resume"` Pincode string `json:"pinCode"` }
这种方式更简洁,适合无需区分JSON和DynamoDB字段名的场景。
方法3:手动构造GetItem的Key
如果不想修改结构体,可以绕过MarshalMap,直接构造符合表schema的键:
input := &dynamodb.GetItemInput{ Key: map[string]*dynamodb.AttributeValue{ "Key": { S: aws.String("2323"), }, "Onboarding": { S: aws.String("The Big New Movie"), }, }, TableName: aws.String("tablename"), }
直接指定表的主键字段名和对应值,从根源避免映射错误。
内容的提问来源于stack exchange,提问作者Shivam Sourav Jha
相关产品推荐
相关产品推荐

