【问题标题】:DynamoDB - Create primary key and attribute if doesn't exist otherwise getDynamoDB - 如果不存在则创建主键和属性,否则获取
【发布时间】:2021-11-13 18:45:31
【问题描述】:

我正在使用 DynamoDB,我只想在主键不存在时创建主键和属性。

如果主键存在,我返回主键和属性。

到目前为止,如果主键不存在,我已经对其进行了更新,但我遇到的问题是,即使主键 alexaDeviceId 已经存在,它仍在更新属性 connectionString

const str = randomize('Aa0', 6);

  const params = {
    TableName: "alexa-connections-table",
    Key: {
      "alexaDeviceId": {
        S: process.env.TEST_ALEXA_DEVICE_ID
      }
    },
    ExpressionAttributeNames: {
      "#CS": "connectionString"
    },
    ExpressionAttributeValues: {
      ":connection": {
        S: str
      }
    },
    ReturnValues: "ALL_NEW",
    UpdateExpression: "SET #CS = :connection"
  };
  

  try {
    var result = await dynamodb.updateItem(params).promise();
    console.log('Results: ' + JSON.stringify(result));

    return res.status(200).send(JSON.stringify(result));
  } catch (err) {
    console.log(err);
    return res.status(500).send({ reason: err });
  }

例如,当我第一次使用空的 dynamoDB 表运行 lambda 函数时:

它应该添加主键 alexaDeviceId 和 6 位属性(按预期工作)

Column alexaDeviceId: AHJYGV...
Column connectionString: 5Dz2SD

当我再次运行程序时

它不应该做任何更新并返回

{"Attributes":{"connectionString":{"S":"5Dz2SD"},"alexaDeviceId":{"S":"AHJYGV..."}}

而是更新connectionString 并返回一个新值(意外结果)

{"Attributes":{"connectionString":{"S":"DxBVmH"},"alexaDeviceId":{"S":"AHJYGV..."}}

如果alexaDeviceId 主键已存在,如何添加不更新connectionString 的条件?

编辑:_____________________________________________________

我尝试使用putItem,但我无法找出正确的语法:

const str = randomize('Aa0', 6);

  const params = {
    TableName: "alexa-connections-table",
    Item: {
      "alexaDeviceId": {
        S: process.env.TEST_ALEXA_DEVICE_ID
      },
      "connectionString": {
        S: str
      }
    },
    ExpressionAttributeValues: {
      ':ADI': {'S': process.env.TEST_ALEXA_DEVICE_ID}
    },
    ConditionExpression: 'if_not_exists(alexaDeviceId, :ADI)'
  };
  

  try {
    var result = await dynamodb.putItem(params).promise();
    console.log('Results: ' + JSON.stringify(result));

    return res.status(200).send(JSON.stringify(result));
  } catch (err) {
    console.log(err);
    return res.status(500).send({ reason: err });
  }

给我错误:

ValidationException: Invalid ConditionExpression: The function is not allowed in a condition expression; function: if_not_exists

【问题讨论】:

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


    【解决方案1】:

    我使用 .putItem() 代替 .updateItem() 和 ConditionExpression:

    ConditionExpression: 'attribute_not_exists(#ADI)'

    const str = randomize('Aa0', 6);
    
    const params = {
        TableName: "alexa-connections-table",
        Item: {
          "alexaDeviceId": {
            S: process.env.TEST_ALEXA_DEVICE_ID
          },
          "connectionString": {
            S: str
          }
        },
        ExpressionAttributeNames: {
          "#ADI": "alexaDeviceId"
        },
        ConditionExpression: 'attribute_not_exists(#ADI)'
      };
      
    
      try {
        var result = await dynamodb.putItem(params).promise();
        console.log('Results: ' + JSON.stringify(result));
    
        return res.status(200).send(JSON.stringify(result));
      } catch (err) {
        console.log(err);
        return res.status(500).send({ reason: err });
      }
    

    如果该表中不存在主键,则会创建一个具有属性connectionString 的新项目。

    console.log('Results: ' + JSON.stringify(result));

    返回ConditionalCheckFailedException

    ConditionalCheckFailedException: The conditional request failed 如果特定的主键已经存在。

    如果不存在则返回{}(意味着.putItem() 成功)。

    【讨论】:

    【解决方案2】:

    在更新前查询特定属性的数据库。

    参考:Query dynamodb for a specific field

    【讨论】:

    • 我认为有一种方法可以在不执行两个查询的情况下做到这一点
    • 步骤 3.5:更新项目(有条件地) 下面的程序展示了如何使用带有条件的 UpdateItem。如果条件评估为真,则更新成功;否则,不执行更新。参考:docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
    • 1) 查询表示该项目不存在; 2)其他人添加项目; 3)您覆盖它,因为(1)表示该项目不存在。
    • 尝试使用 ReturnValues: "ALL_OLD" 。 PutItem 可能会在更新之前返回项目,或者根本不返回。参考:stackoverflow.com/questions/39451505/…
    猜你喜欢
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 2023-03-23
    • 2010-10-16
    • 2018-07-26
    • 2023-03-17
    • 2012-02-04
    • 2021-04-01
    相关资源
    最近更新 更多