Lambda Golang PutItem和MarshalMap到DynamoDB

5
我正在尝试使用Golang将Lambda中的数据加载到DynamoDB中,但是编组方法只生成空项。我定义了如下类型结构...
type Flight struct {
    id          string
    destination string
    airline     string
    time        string
    latest      string
}

我接下来会按以下方式填充一个切片:

func PutToDynamo(Flights []Flight, kind string) {

Flights := []Flight{}

for _, row := range rows {
    columns := row.FindAll("td")

    f := columns[0].Text() //all these are strings
    a := columns[1].Text()
    i := columns[2].Text()
    t := columns[4].Text()
    l := columns[5].Text()

    flight := Flight{
        id:          i,
        destination: f,
        airline:     a,
        time:        t,
        latest:      l,
    }
    Flights = append(Flights, flight)

然后我尝试将其加载到DynamoDB中。

func PutToDynamo(flights []Flight, kind string) {
    for _, flight := range flights {
        av, err := dynamodbattribute.MarshalMap(flight)

        input := &dynamodb.PutItemInput{
            Item:      av,
            TableName: aws.String("flights"),
        }

        _, err = svc.PutItem(input)
        fmt.Println("FLIGHT: ", input.GoString())

如果我打印“flight”,我可以看到所有我期望的信息。然而,输入的GoString()只返回以下内容...
 {
   Item: {
   },
   TableName: "flights"
 }

我在Lambda中从DynamoDB获取数据时,出现了一个错误。

ValidationException: One or more parameter values were invalid: Missing the key id in the item

有任何想法吗?我尝试在结构体中放置json:“id”等内容,但没有区别。
谢谢!

尝试过删除 Slice 迭代,将记录直接放入 Dynamo 中生成,仍然得到空白 :( - NickS
1个回答

6
你的结构体中的字段是未导出的,这可能是为什么 Dynamo Marshal 没有将其编组的原因(快速查看源代码表明 Dynamo 和 JSON Marshal 方法有些相似)。根据常规的 Golang JSON Marshal,来自 documentation 的说明如下:
“JSON 包只访问结构类型的导出字段(以大写字母开头的字段)。因此,结构体的导出字段才会出现在 JSON 输出中。”
两个方法可以解决这个问题:
a)更改您的结构体,使其具有导出字段。
type Flight struct {
    Id          string
    Destination string
    Airline     string
    Time        string
    Latest      string
}

b) 如果您不想更改您的结构(例如,如果它在代码中被引用很多次,重构将是一件麻烦的事情),则可以添加自定义的Marshal和Unmarshal函数,并将您的结构隐藏在自定义的导出结构之间(下面的代码未经测试 - 仅供简要参考):

type Flight struct {
    id          string
    destination string
    airline     string
    time        string
    latest      string
}

type FlightExport struct {
        Id          string
        Destination string
        Airline     string
        Time        string
        Latest      string
}

func(f *Flight) MarshalJSON()([] byte, error) {
    fe: = &FlightExport {
        ID: f.id,
        Destination: f.destination,
        Airline: f.airline,
        Time: f.time,
        Latest: f.latest
    }

        return json.Marshal(fe)
}

func(f *Flight) UnmarshalJSON(data[] byte) error {
    var fe FlightExport
    err: = json.Unmarshal(data, &fe)
    if err != nil {
        return err
    }

    f.id = fe.ID
    f.destination = fe.Destination
    f.airline = fe.Airline
    f.time = fe.Time
    f.latest = fe.Latest

    return nil
}

谢谢!!!我已经花了数小时在这上面,否则永远也不会想到。导出它们后一切都工作得很完美。虽然因为我无处不用小写字母而进行重构将会很麻烦,但还是值得将其迁移到无服务器架构中,以保持代码的简单/高效性。 - NickS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接