【问题标题】:How to backfill new AppSync fields using AWS Amplify如何使用 AWS Amplify 回填新的 AppSync 字段
【发布时间】:2020-03-14 01:56:47
【问题描述】:

我正在使用 GraphQL 向我的一个 AppSync 表中添加一个排序字段。新架构如下所示:

type MyTable
  @model
  @auth(rules: [{allow: owner}])
  @key(name: "BySortOrder", fields: ["sortOrder"], queryField: "tableBySortOrder")
{
  id: ID!
  name: String!
  sortOrder: Int
}

但是,当使用 tableBySortOrder 检索列表时,我得到一个空列表,因为新字段 sortOrder 为空。

我的问题是,我如何将这些数据回填到 DynamoDB 表中,这样我的现有用户才不会被这一新变化所干扰?对于传统数据库,我会运行 SQL 更新:UPDATE MyTable SET sortOrder = #

但是,我是 NoSQL/AWS 的新手,除了在用户登录我的应用程序时构建一个回填脚本外,找不到其他方法。感觉很hacky。处理这种情况的最佳做法是什么?

【问题讨论】:

    标签: amazon-dynamodb aws-amplify aws-appsync dynamodb-queries


    【解决方案1】:

    您是否已经在 DDB 中创建了新字段? 如果是,我认为您应该在进行客户端更改之前回填它。

    编写一个脚本来迭代和更新表格。选项:

    • Java - 如果您正在运行任何集成测试,请调用 updateItem 以更新表。
    • Bash - 使用 AWS CLI:aws dynamodb scan --table-name item_attributes --projection-expression "whatever" > /tmp/item_attributes_table.txt,然后是 aws dynamodb update-item --table-name item_attributes --key。这是一种肮脏的方式。
    • Python - 与上述相同的逻辑。

    【讨论】:

      【解决方案2】:

      最终使用了类似于 Sunny 建议的 nodejs 脚本:

      const AWS = require('aws-sdk')
      
      AWS.config.update({
        region: 'us-east-1'
      })
      
      // To confirm credentials are set
      AWS.config.getCredentials(function (err) {
        if (err) console.log(err.stack)
        // credentials not loaded
        else {
          console.log('Access key:', AWS.config.credentials.accessKeyId)
          console.log('Secret access key:', AWS.config.credentials.secretAccessKey)
        }
      })
      
      const docClient = new AWS.DynamoDB.DocumentClient()
      
      const table = 'your-table-dev'
      
      const params = {
        TableName: table
      }
      
      const itemMap = new Map()
      
      // Using scan to retrieve all rows
      docClient.scan(params, function (err, data) {
        if (err) {
          console.error('Unable to query. Error:', JSON.stringify(err, null, 2))
        } else {
          console.log('Query succeeded.')
          data.Items.forEach(item => {
            if (itemMap.has(item.owner)) {
              itemMap.set(item.owner, [...itemMap.get(item.owner), item])
            } else {
              itemMap.set(item.owner, [item])
            }
          })
      
          itemMap.forEach(ownerConnections => {
            ownerConnections.forEach((connection, index) => {
              connection.sortOrder = index
              update(connection)
            })
          })
        }
      })
      
      function update(connection) {
        const params = {
          TableName: table,
          Key: {
            'id': connection.id
          },
          UpdateExpression: 'set sortOrder = :s',
          ExpressionAttributeValues: {
            ':s': connection.sortOrder,
          },
          ReturnValues: 'UPDATED_NEW'
        };
      
        console.log('Updating the item...');
        docClient.update(params, function (err, data) {
          if (err) {
            console.error('Unable to update item. Error JSON:', JSON.stringify(err, null, 2));
          } else {
            console.log('UpdateItem succeeded:', JSON.stringify(data, null, 2));
          }
        });
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-27
        • 1970-01-01
        • 2020-12-28
        • 2020-08-20
        • 1970-01-01
        • 2022-12-29
        • 2021-04-24
        • 2019-10-19
        • 2019-01-15
        相关资源
        最近更新 更多