snorberhuis
snorberhuis

Reputation: 3286

Upsert with optimistic locking with DynamoDB and Boto3

I am trying to implement an upsert of an item into DynamoDB with optimistic locking. I have the update portion working with a ConditionExpression to check the version. But this fails the save portion as the ConditionExpression is false for saving. Is it possible to write the ConditionExpression so that it will handle both situations?

My code:

result = copy.copy(user)
table = get_db_table()

current_version = result.get_version()
result.update_version()

try:
    table.put_item(
        Item=result.to_table_item(),
        ConditionExpression=Attr(result.get_version_key()).eq(current_version)
    )
except ClientError as error:
    logger.error(
        "Saving to db failed with '%s'",
        str(error))
    # Restore version
    result.set_version(current_version)
    raise Exception(ErrorCode.DB_SAVE) from error
return result

Upvotes: 1

Views: 2810

Answers (1)

Matthew Pope
Matthew Pope

Reputation: 7679

Basically, you need to make sure the attribute exists before you can compare something to it. Your condition expression string should be

does_not_exist(current_version) or current_version = expected_current_version

Using Boto3, you can create this using

Attr(result.get_version_key()).not_exists() | Attr(result.get_version_key().eq(current_version))

Upvotes: 5

Related Questions