如何在DynamoDB UpdateItem

时间:2019-08-22 14:01:02

标签: go amazon-dynamodb aws-sdk-go

编辑问题:尝试更新map [] interface字段时出现错误400。

在使用UpdateItem时,我坚持要在DynamoDB中更新我的数组对象,特别是在我的数组对象(在本例中为“作者”字段)上。

&awserr.requestError{awsError:(*awserr.baseError)(0xc000204140), statusCode:400, requestID:"QU2MMAJVDRM0JHJEPOE93VJPSVVV4KQNSO5AEMVJF66Q9ASUAAJG", bytes:[]uint8(nil)}

在具有相同结构的PutItem上使用时,我没有遇到任何问题。 我不确定自己缺少什么,AWS发出的错误对我来说也不是很清楚。

结构:

type Book struct {
    Id          int            `json:":id"`
    Title       string         `json:":title"`
    Photo       Photo          `json:":photo"`
    Authors     []Author       `json:":authors"`
}

type Author struct {
    Id          int            `json:":id"`
    Name        string         `json:":name"`
}

我已经尝试过 更新代码:

input := &dynamodb.UpdateItemInput{
        TableName:                 aws.String("books"),
        Key:                       key,
        UpdateExpression:          aws.String(updateExp),
        ExpressionAttributeValues: value,
    }

更新表达式:

"SET title = :title, photo = :photo, authors = list_append(authors, :authors)"

我也已经尝试过

authors = :authors

由于我计划每次都替换整个 Authors 值,但似乎可以完成这项工作。

当我记录我的ExpressionAttributeValue时,它看起来像这样

ExpressionAttributeValues: {
        :authors: {
          L: [{
              M: {
                id: {
                  N: "1"
                },
                name: {
                  S: "Bob"
                }
              }
            },{
              M: {
                name: {
                  S: "Arthur"
                },
                id: {
                  N: "2"
                }
              }
            }]
        },
        :title: {
          S: "Jumanji"
        },
        :description: {
          S: "Jungle Book"
        },
        :photo: {
          M: {
            original: {
              S: "sample.jpg"
            }
          }
        }
      }

我已经测试过删除authors字段更新(以UpdateExpression根据可用数据进行调整的方式进行编码),并且所有其他字段更新都可以正常工作,所以我的问题实际上只是更新[] struct类型。

1 个答案:

答案 0 :(得分:0)

尽管您的问题有点令人困惑,但我认为问题在于如何使用updateItem更新整个数组。我遇到了类似的问题(这就是为什么我找到了您的问题),但是我设法自己解决了这个问题,因为无论如何,用DynamoDB更新数组并没有太多的选择。因此,在完成此操作后,我一直打开该浏览器的选项卡,现在我可以提供一些可能的有用帮助:

因此,您想更新您的authors数组(以及标题,描述和照片等其他信息)。假设您的作者看起来像这样:

const authors = [
  {
    id: 1,
    name: "Bob"
  },
  {
    id: 2,
    name: "Arthur"
  }
];

我将首先运行一个for循环,因为您可以在数组中拥有不止两个项目,以便为更新正确映射它。像这样:

const authArray = []
for (const a of authors) {
  authArray.push({ M: { 
    id:   { N: a.id.toString() }, // if id is a number, transform to string
    name: { S: a.name }
  } });
}

然后我们准备更新:

const params = {
    TableName: 'your-table-name',
    Key: { "UserID": { S: userID } },
    ExpressionAttributeValues: {
          ":au": { L: authArray },
          ":ti": { S: "Jumanji" },
          ":de": { S: "Jungle Book" },
          ":ph": { M: { original: { S: "sample.jpg" } }
    }, 
    ExpressionAttributeNames: {
          "#A": "authors",
          "#T": "title", 
          "#D": "description",
          "#P": "photo"
    }, 
    UpdateExpression: 
          "SET #A=:au, #T=:ti, #D=:de, #P=:ph",
    ReturnValues: 
          "ALL_NEW"
}

dynamoDB.updateItem(params, function (err, item) {
     if (err) {
        console.log('UPDATE FAILED! => ', err);
        cb(err);
     } else {
        console.log('SUCCESS UPDATE! => ', item);
        item = item.Attributes;
        cb(null, item);
     }

我希望这对您足够好。它对我有用。