将DynamoDB映射分解为像GO结构一样强烈键入的内容的简短帖子。如果您想直接跳到某个代码,这里是github gist
那么,什么是“ Unmarshalling”?这是拿出一个数据并将其转换为另一个数据的行为。例如,当我们将数据存储在DynamoDB中时,本机数据类型之一是“映射”。地图实际上不过是字典/钥匙值类型查找。将字典视为具有密钥和后续值的数据结构。键必须是唯一的。以这些数据为例
{
"Roles": {
"1": {
"name": "Role number 1",
"id": 1
},
"2": {
"name": "Role number 2",
"id": 2
}
},
"SK": "ROLE#1234",
"PK": "USERPROFILE#1000130",
"EntityType": "UserRole"
}
角色属性是一张地图。它包含["1"]
和["2"]
的键。然后,每个键中的每个键都包含另一个地图。这些看起来很像JSON对象,并且出于各种意图和目的,可以这样认为它们是可以的。
因此,使用这些数据,我们如何将其纳入看起来像这样的东西
type UserRole struct {
EntityType string `dynamodbav:"EntityType"`
Roles []Role `dynamodbav:"Roles"`
}
type Role struct {
Id int
Name string
}</pre>
UserRole
struct具有EntyType属性以及具有角色结构的角色切片。每个字段还具有将它们描述为在Dyanamodb属性值中用与列名相对应的名称表示的事物。随时阅读更多here
开始摘要的第一步是构建UserRole
并将其解散。
ur := &UserRole{}
_ = dynamodbattribute.UnmarshalMap(i, ur)</pre>
默认情况下,这实际上只会删除GO库知道如何处理的字段。与使用JSON UMARSHALLING合作时非常相似,可以使用DynamoDB
进行同样的操作
func (ur *UserRole) UnmarshalDynamoDBAttributeValue(value *dynamodb.AttributeValue) error {
for k, kv := range value.M {
if k == "EntityType" {
ur.EntityType = *kv.S
} else if k == "Roles" {
for _, nkv := range kv.M {
r := &Role{}
err := dynamodbattribute.UnmarshalMap(nkv.M, r)
if err != nil {
return err
}
ur.Roles = append(ur.Roles, *r)
}
}
}
return nil
}
请注意,您可以旋转传递的属性值的密钥/值对。对于每个键,您可以确定内部的对象类型。例如,EntityType
字段是一个字符串。这很简单。
但是有了Roles
字段,还有另一张地图要处理。再一次,只需汇总该变量,然后将自定义步骤一层进一步
func (r *Role) UnmarshalDynamoDBAttributeValue(value *dynamodb.AttributeValue) error {
for k, kv := range value.M {
if k == "id" {
v, _ := strconv.ParseInt(*kv.N, 10, 32)
r.Id = int(v)
} else if k == "name" {
r.Name = *kv.S
}
}
return nil
}
就在那里。来自DynamoDB地图的Umarshalled自定义类型。它也没有太多,但是这种超级强大,因为您可以意识到使用自定义代码存储在GO结构中的任何类型的数据。
希望这很有帮助!