英文:
How to unmarshal map[string]*dynamodb.AttributeValue?
问题
我正在查询一个 DynamoDB 表,并需要对查询结果进行 UnmarshalMap,即将记录转换为 JSON 格式。
[{"movie":"Joker","year":"2019"}]
或者类似这样的格式:
[{"movie":"Joker","year":"2019"}, {"movie":"Cruella","year":"2021"}]
结构体定义如下:
type Movies struct {
Movie string `json:"movie" bson:"movie" dynamodbav:"movie"`
Year string `json:"year" bson:"year" dynamodbav:"year"`
}
type Database struct {
User string `json:"user" bson:"user" dynamodbav:"user"`
List []*Movies `json:"movies" bson:"movies" dynamodbav:"movies"`
}
listOfMovies := Database{}
if err := dynamodbattribute.UnmarshalMap(tableOutput.Item, &listOfMovies); err != nil {
log.Println(err)
return nil, err
}
return listOfMovies.List, nil
tableOutput.Item
是一个包含数据库记录的映射,我没有收到任何错误,但是 Movies 列表为空。我不明白我做错了什么。UnmarshalMap 应该是这样工作的吗?
英文:
I am querying a DynamoDB table and need to UnmarshalMap i.e. query output.
The record in a table is JSON.
[{"movie":"Joker","year":"2019"}]
Or something like this
[{"movie":"Joker","year":"2019"}, {"movie":"Cruella","year":"2021"}]
type Movies struct {
Movie string `json:"movie" bson:"movie" dynamodbav:"movie"`
Year string `json:"year" bson:"year" dynamodbav:"year"`
}
type Database struct {
User string `json:"user" bson:"user" dynamodbav:"user"`
List []*Movies `json:"movies" bson:"movies" dynamodbav:"movies"`
}
listOfMovies = Database{}
if err := dynamodbattribute.UnmarshalMap(tableOutput.Item, &listOfMovies); err != nil {
log.Println(err)
return nil, err
}
return listOfMovies.List, nil
tableOutput.Item
is a map and contains a record from database, I get no errors but the list of Movies is empty. I don't understand what I am doing wrong. Is this how UnmarshalMap should work?
答案1
得分: 1
为了管理您的场景,我编写了一个简单的示例程序,以便给您一个关于写入和读取过程的概述。下面是我示例应用程序的代码:
package main
import (
"context"
"encoding/json"
"fmt"
"dynamodbmovie/utils"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
var cfg *aws.Config
func main() {
cfg, _ = utils.GetAwsConfig()
dynaClient := dynamodb.NewFromConfig(*cfg)
// 创建表
dynaClient.CreateTable(context.TODO(), &dynamodb.CreateTableInput{
TableName: aws.String("movies"),
AttributeDefinitions: []types.AttributeDefinition{
{
AttributeName: aws.String("user"),
AttributeType: types.ScalarAttributeTypeS,
},
},
KeySchema: []types.KeySchemaElement{
{
AttributeName: aws.String("user"),
KeyType: types.KeyTypeHash,
},
},
BillingMode: types.BillingModePayPerRequest,
})
defer func() {
dynaClient.DeleteTable(context.TODO(), &dynamodb.DeleteTableInput{
TableName: aws.String("movies"),
})
}()
// 加载表
dynaClient.PutItem(context.TODO(), &dynamodb.PutItemInput{
TableName: aws.String("movies"),
Item: map[string]types.AttributeValue{
"user": &types.AttributeValueMemberS{Value: "user1"},
"movies_list": &types.AttributeValueMemberS{Value: `[{"movie":"Joker","year":"2019"}, {"movie":"Cruella","year":"2021"}]`},
},
})
// 读取表
var filmString string
res, _ := dynaClient.GetItem(context.TODO(), &dynamodb.GetItemInput{
TableName: aws.String("movies"),
Key: map[string]types.AttributeValue{
"user": &types.AttributeValueMemberS{Value: "user1"},
},
})
attributevalue.Unmarshal(res.Item["movies_list"], &filmString)
myDb := &Database{
User: "user1",
}
json.Unmarshal([]byte(filmString), &myDb.List)
fmt.Println(len(myDb.List))
}
utils/models.go
package main
type Movies struct {
Movie string `json:"movie"`
Year string `json:"year"`
}
type Database struct {
User string `json:"user"`
List []*Movies `json:"movies"`
}
如您所见,除了json
标签注释之外,不需要其他标签注释。为了满足您的需求,我将电影列表存储在 DynamoDB 中作为一个 JSON 字符串,因此您需要进行字符串的编组/解组操作,这很容易。然后,通过第二次解组,您可以将信息放入Database
结构中。
请注意,为了示例的简洁性,我没有考虑错误处理和编写良好软件的原则。
英文:
To manage your scenario, I wrote down a trivial sample program to give you an overview of the writing and reading process. Below you can find the code for my sample application:
package main
import (
"context"
"encoding/json"
"fmt"
"dynamodbmovie/utils"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
var cfg *aws.Config
func main() {
cfg, _ = utils.GetAwsConfig()
dynaClient := dynamodb.NewFromConfig(*cfg)
// create table
dynaClient.CreateTable(context.TODO(), &dynamodb.CreateTableInput{
TableName: aws.String("movies"),
AttributeDefinitions: []types.AttributeDefinition{
{
AttributeName: aws.String("user"),
AttributeType: types.ScalarAttributeTypeS,
},
},
KeySchema: []types.KeySchemaElement{
{
AttributeName: aws.String("user"),
KeyType: types.KeyTypeHash,
},
},
BillingMode: types.BillingModePayPerRequest,
})
defer func() {
dynaClient.DeleteTable(context.TODO(), &dynamodb.DeleteTableInput{
TableName: aws.String("movies"),
})
}()
// load table
dynaClient.PutItem(context.TODO(), &dynamodb.PutItemInput{
TableName: aws.String("movies"),
Item: map[string]types.AttributeValue{
"user": &types.AttributeValueMemberS{Value: "user1"},
"movies_list": &types.AttributeValueMemberS{Value: `[{"movie":"Joker","year":"2019"}, {"movie":"Cruella","year":"2021"}]`},
},
})
// read table
var filmString string
res, _ := dynaClient.GetItem(context.TODO(), &dynamodb.GetItemInput{
TableName: aws.String("movies"),
Key: map[string]types.AttributeValue{
"user": &types.AttributeValueMemberS{Value: "user1"},
},
})
attributevalue.Unmarshal(res.Item["movies_list"], &filmString)
myDb := &Database{
User: "user1",
}
json.Unmarshal([]byte(filmString), &myDb.List)
fmt.Println(len(myDb.List))
}
utils/models.go
package main
type Movies struct {
Movie string `json:"movie"`
Year string `json:"year"`
}
type Database struct {
User string `json:"user"`
List []*Movies `json:"movies"`
}
As you can see, there is no need for other tag annotation except the json
ones. To accomplish your needs, I stored in DynamoDb the list of movies as a JSON string so you've to marshal/unmarshal to and from a string which is easy. Then, with a second unmarshal you can bring the information on the Database
struct.
> Please note, that for the sake of example, I didn't take into consideration the error management and the principles for writing good software.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论