0

I have a DynamoDB table defined as follows:

Partition key: id (string)

Sort key: ruleId (string)

Example item:

{ "id": "123", "ruleId": "abc" }

What I want is SQL-like behavior:

INSERT INTO table (id, ruleId) VALUES ('123', 'abc')
ON CONFLICT DO NOTHING;

In other words:

Allow multiple rows with the same id but different ruleIds (e.g. (123, abc) and (123, def)).

Prevent inserting the same (id, ruleId) pair twice and perform some client side if the put fails. I am using the ConditionFailedException to track whether an item is inputted or not.

Table schema (current)

Right now, my table has:

Partition key: id (string)
Sort key: ruleId (string)

Example item:

{
  "id": "123",
  "ruleId": "abc"
}

What I’ve tried

Using the AWS SDK PutItem, I’ve experimented with condition expressions to enforce uniqueness:

ConditionExpression: "attribute_not_exists(id) AND attribute_not_exists(ruleId)"

This rejects inserts whenever the same id already exists (even if it’s a different ruleId).

ConditionExpression: "attribute_not_exists(id)"

This seems to reject new ruleIds for the same id.

ConditionExpression: "attribute_not_exists(ruleId)"

This works sometimes, but I’m not sure it’s the correct way to enforce uniqueness of (id, ruleId) pairs.

My confusion

Do I have to choose only one partition key, or can both id and ruleId be part of the key?

If I stick with (id, ruleId) as the composite primary key (partition key + sort key), what’s the correct condition expression to prevent overwriting an existing pair but allow new combinations?

What’s the best way to implement SQL-like behavior where the insert returns a boolean (or the item) to indicate whether the row was newly inserted or already existed?

2
  • This question is similar to: DynamoDB unique primary key ConditionExpression. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Sep 23 at 22:02
  • I believe your issues stem from misunderstanding what attribute_not_exists(id) and attribute_not_exists(ruleId) really mean. They're evaluates not against the table, but against a single document, which is defined by the (id, ruleId) pair. Since that document either does or doesn't exist, both expressions always have the same truth-value. See this answer for more. Commented Sep 23 at 22:04

1 Answer 1

0

DynamoDB only ever rejects a condition on a single item, the one where the PutItem is actioning.

In other words, it'll only reject if the item you're inserting already exists, that's both id and ruleId.

It never checks just the id or ruleId regardless if you check for either or both attributes.

By that standard, I believe a condition check will do exactly what you require.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.