首页 > 解决方案 > DynamoDB - 如果不存在则创建主键和属性,否则获取

问题描述

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

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

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

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..."}}

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

编辑:___________________________________________________________________

我试过用 aputItem代替,但我不知道正确的语法:

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.jsamazon-web-servicesaws-lambdaamazon-dynamodbdynamodb-queries

解决方案


我使用.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()成功)。


推荐阅读