【问题标题】:update attributes in a dynamodb record更新 dynamodb 记录中的属性
【发布时间】:2020-07-09 02:47:11
【问题描述】:

我正在尝试更新我的 dynamodb 表中的现有记录。 如下所示,我的表中有一个项目

let params = {
   TableName: proces.env.dynamoDbTable,
   Item: {
      productId: "id",
      att1: val1,
      att2: val2
      }
 }

我想执行更新。我正在使用 aws dynamodb sdk 的更新方法并传递如下参数

let aws = require('aws-sdk');
 let dbb = new aws.DynamoDb.DocumentClient();
 let params = {
  TableName: process.env.tableName,
  Key: {productID}
  ExpressionAttributeNames: { "#updatedAt" : "updatedAt" }
  ExpressionAttributeValues: {":u":moment().unix(), ":val1" : a, ":val2": b}
  UpdateExpression: "SET att1 = :val1, att2: val2, #updatedAt: :u"
 }
// a, b are passed as argument to function and are optional
dbb.update(params).promise()

当一个参数丢失时,发电机会引发 ExpressionAttributeValue 丢失异常,我知道它是直接的。有没有办法可以使用提供的属性更新我的项目

【问题讨论】:

  • “当参数丢失时”是什么意思?
  • 另外,An expression attribute name must begin with a pound sign (#), docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
  • @LucasD 这是我的更新表达式的样子 "SET #name =:n, #slug = :s, #updatedAt = :u,description= :d, thumbnail= :t" 我收到一个req 从前端更新一个名为“描述”的参数。当我调用更新方法时,它会抛出一个代码“ValidationException”缺少属性值:n。我明白,由于我没有传递值,所以预计会出现错误。我怎样才能只更新我收到的几个属性,而其余的保持不变?
  • 请用正确的格式更新您的问题。希望其他人能提出更优雅的解决方案
  • @LucasD 当然我会重新格式化问题。感谢您的回答。我会在这里尝试并更新。 :)

标签: node.js amazon-web-services amazon-dynamodb dynamodb-queries amazon-dynamodb-local


【解决方案1】:

不幸的是,dynamodb 并没有让这变得容易。但是你可以使用一些花哨的 js 来动态创建 params 对象:

  // for some object `attrs` we find which keys we need to update
  const keys = Object.keys(attrs);
  const values = Object.values(attrs);

  // get a list of key names and value names to match the dynamodb syntax
  const attributeKeyNames = keys.map((k) => '#key_' + k);
  const attributeValueNames = keys.map((k) => ':val_' + k);

  // create individual expressions for each attribute that needs to be updated
  const expressions = attributeValueNames.map((attr, i) => {
    return `${attributeKeyNames[i]} = ${attr}`;
  });

  // add the SET keyword to the beginning of the string
  // and join all the expressions with a comma
  const UpdateExpression = 'SET ' + expressions.join(', ');

  // I use `zipObject()` from lodash https://lodash.com/docs/4.17.15#zipObject
  // it makes an object map from two arrays where the first is the keys and
  // the second is the values
  const ExpressionAttributeValues = _.zipObject(attributeValueNames, values);
  const ExpressionAttributeNames = _.zipObject(attributeKeyNames, keys);

  // now you have all the params
  const params = {
    TableName,
    Key: {
      uuid,
    },
    UpdateExpression,
    ExpressionAttributeValues,
    ExpressionAttributeNames,
  };

【讨论】:

    【解决方案2】:

    Lucas D's answer 效果很好。不过要记住几点:

    如果您将带有唯一键的对象发送到更新函数中,则必须在映射表达式数组之前删除该键,否则它将包含在查询中并出现错误:

    const newObject = {...originalObject}
    delete newObject.unique_key
    

    如果您不能或不想使用 Lodash,您可以使用 Object.assign 来映射您的键/值数组:

    const ExpressionAttributeValues = Object.assign(...attributeValueNames.map((k, i) => ({[k]: values[i]})));
    const ExpressionAttributeNames = Object.assign(...attributeKeyNames.map((k, i) => ({[k]: keys[i]})));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多