Home > OS >  DynamoDB - Create primary key and attribute if doesn't exist otherwise get
DynamoDB - Create primary key and attribute if doesn't exist otherwise get

Time:09-21

I'm using DynamoDB where I want to create a primary key and an attribute only if the primary key doesn't exist.

If the primary key exists, I return the primary key and the attribute.

So far I've gotten it to upsert if the primary key doesn't exist, but the issue I'm running into, is that it's still updating the attribute connectionString even when the primary key alexaDeviceId already exists:

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 });
  }

So for instance when I first run the lambda function with an empty dynamoDB table:

it should add primary key alexaDeviceId and 6 digit attribute (working as intended)

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

when I run the program again

it should NOT do any updates and return

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

instead it's updating the connectionString and returning a new value (unexpected result)

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

How do I add a condition to not update the connectionString if the alexaDeviceId primary key already exists?

Edit:___________________________________________________________________

I've tried using a putItem instead but I can't figure out the correct syntax:

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 });
  }

Giving me the error:

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

CodePudding user response:

I used .putItem() instead of .updateItem() and the 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 });
  }

This creates a new Item with the attribute connectionString if the primary key does not exist in that table.

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

returns a ConditionalCheckFailedException

ConditionalCheckFailedException: The conditional request failed if a specific primary key already exists.

It returns {} if one does not exist (meaning the .putItem() was successful).

CodePudding user response:

Query DB for specific attribute before doing update.

Ref : Query dynamodb for a specific field

  • Related