dynamodb doc client forcing a put (not update) into a table

272 Views Asked by At

I am trying to make a put into a dynamo table I created called events using the aws-sdk for javascript, in particular AWS.DynamoDB.DocClient(). It was set up to simply track any and all user events and is a super simple structure. The structure is as follows:

cognitoId (Primary Key) eventType timestamp
* * *

The problem I am having is that instead of inserting or putting a new entry into the table, it updates instead if the user is already in the table. Now I know why it's doing this, because the cognitoId is the primary key and this is the expected functionality of the put function. It updates if the primary key is found and adds if it's not.

I have tried a few different methods, even ConditionalExpression, but I am still not able to essentially force add an entry regardless of the primary key.

My basic implementation if below:

exports.handler = async (event, context, callback) => {
  const { EventsTable } = process.env;
  const { detail } = event;
  const {
    sub,
    eventType = 'Post Authentication'
  } = detail;

  const timestamp = moment().tz("America/New_York").format();

  const params = {
    TableName: EventsTable,
    Item: {
      cognitoId: sub,
      eventType,
      timestamp,
    },
    ExpressionAttributeNames: {
      '#timestamp': 'timestamp'
    },
    ExpressionAttributeValues: {
      ':timestamp': timestamp
    },
    ConditionExpression: '#timestamp <> :timestamp'
  }

  console.log(params);

  try {
    const data = await docClient.put(params).promise();
    callback(null, event);
  }
  catch (err) {
    console.log(err);
    callback(null, event)
  }
}

My question is, what is the best way to implement forcing an insert regardless if the primary key is already found?

1

There are 1 best solutions below

0
On

Now I know why it's doing this, because the cognitoId is the primary key and this is the expected functionality of the put function. It updates if the primary key is found and adds if it's not.

It sounds like you have a good understanding of why this is happening. It doesn't sound like the Cognito ID alone is enough to uniquely represent a user event in your specific use case. You might want to take a look at a composite primary key. That is, a primary key made up of more than one piece of information. For example, maybe you could use the Cognito ID and timestamp field to uniquely identify an event. Or if user events can happen at the same time, perhaps some sort of unique identifier (e.g. UUID/KSUID/ULID).

Consider including the timestamp in a composite primary key. That way, you can have an item collection to aggregate user events over time.