DynamoDBSaveExpression с условной проверкой GSI - PullRequest
0 голосов
/ 01 ноября 2018

Я хочу сделать обновление, но условная проверка, которую я хочу добавить, основана не на хэше / диапазоне основной таблицы, а на GSI.

По сути, я хочу отменить сохранение, если данный атрибут (т. Е. Хеш GSI) уже существует.

Например, в воображаемой таблице сотрудников «SSN» - это ключ хеша, а в «EmployeeId» имеется GSI. Оба эти атрибута должны быть уникальными во всем. Сохраняя сотрудника, я хочу убедиться, что ни «SSN», ни «EmployeeId» уже не используются в таблице. Я могу сделать это для хэша таблицы, т.е. SSN, но не для хэша GSI.

Это поддерживается? Я не видел этого в документации.

Спасибо!

1 Ответ

0 голосов
/ 14 декабря 2018

Метод, который вы описали, невозможен при использовании DynamoDB даже с недавно объявленными транзакциями. Причина в том, что ваш GSI в конечном итоге непротиворечив и может не отражать самое современное состояние элементов в вашей таблице, поэтому в GSI нельзя использовать выражение ConditionExpression.

Однако , вы можете достичь аналогичной функциональности, имея отдельную таблицу EmployeeId-InUse. Это может быть просто как один атрибут: employeeId. Поскольку это таблица, а не GSI, вы можете использовать запрос TransactWriteItems для одновременной записи в таблицы EmployeeData и EmployeeId-InUse. Транзакция завершится неудачей, если произойдет сбой какой-либо части транзакции, поэтому вы можете использовать выражение ConditionExpression для Предотвратить перезапись существующего элемента , чтобы гарантировать, что транзакция завершится неудачей, если SSN или EmployeeId уже существует.

Вот пример того, как будет выглядеть часть TransactItems в вашем запросе DynamodB для этого.

“TransactItems”: [
    {
        “Put” : {
            “ConditionExpression” : “attribute_not_exists(ssn)”,
            “Item” : {
                ... employee data goes here ...
             },
            “TableName”: “EmployeeData”
        }
    },
    {
        “Put” : {
            “ConditionExpression” : “attribute_not_exists(employeeId)”,
            “Item” : {
                “employeeId”: {
                      “S” : “Employee1457”
                }
            },
            “TableName”: “EmployeeIDs-InUse”
        }
    }
]

Есть пара вещей, на которые нужно обратить внимание. Обязательно обновляйте таблицу EmployeeId-InUse при каждом добавлении или удалении сотрудника, а также при обновлении employeeId, связанного с данным SSN. Также имейте в виду, что транзакция потребляет вдвое больше емкости, чем обычная запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...