Условная вставка в Dynamodb - PullRequest
0 голосов
/ 14 июня 2019

Я создаю приложение отслеживания отпуска, в котором я хочу сохранить идентификатор пользователя вместе с датой и датой. Я использую Amazono DynamoDB в качестве базы данных, и пользователь вводит отпуск через пользовательскую команду. Например: применить-оставить от даты к дате

Я хочу избежать дублирования записей в базе данных. Например, если пользователь уже подал заявку на отпуск с 06-10-2019 по 10-10-2019 и снова подает заявку на отпуск между теми же датами, он должен получить сообщение о том, что он уже существует, и новая запись должна не быть создан для того же.

Однако пользователь может подать заявку на несколько отпусков, а два пользователя могут сделать отпуск между одними и теми же датами.

Я попытался использовать условное выражение следующим образом:

table.put_item(
            Item={
                'leave_id': leave_id,
                'user_id': user_id,
                'from_date': from_date,
                'to_date': to_date,
            },
            ConditionExpression='attribute_not_exists(user_id) AND attribute_not_exists(from_date) AND attribute_not_exists(to_date)'
        )

, где left_id - ключ раздела. Однако это не работает, и новая строка добавляется каждый раз, даже если это одни и те же даты. Я просмотрел похожие другие вопросы, но не смог понять, как правильно это настроить.

Любые идеи о том, как я должен поступить об этом, или если есть другой дизайн, которому я должен следовать?

1 Ответ

1 голос
/ 14 июня 2019

Если вы вызываете свой код с leave_id, которого еще не существует в таблице, элемент всегда будет вставлен. Если вы называете свой код с leave_id, что действительно уже существует в вашей таблице, вы должны получить An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed сообщение об ошибке.

У меня есть два предложения:

Если вы не хотите менять свою таблицу, вы можете создать вторичный индекс с user_id в качестве ключа раздела, а затем запросить индекс для всех элементов, где у данного пользователя есть from_date и to_date атрибутов. Как это:

table.query(
    IndexName='user_id-index',
    KeyConditionExpression=Key('user_id').eq(user_id),
    FilterExpression=Attr('from_date').exists() & Attr('from_date').exists()
)

Затем вам нужно будет проверить наличие перекрывающихся запросов на отпуск и т. Д. (Например, запрос на отпуск, который начинается до того, как закончится тот, который уже находится на месте). После того, как вы решите, что запрос на отпуск является действительным, вы позвоните put_item.

Другим предложением, и, возможно, лучше, будет создание составного первичного ключа на вашей таблице с user_id в качестве ключа раздела и leave_id в качестве ключа сортировки. Таким образом, вы можете выполнить запрос для всех запросов на отпуск от конкретного пользователя без необходимости создания вторичного индекса.

...