【问题标题】:Condition Expression seems not to be taken into account on DynamoDB PutItemDynamoDB PutItem 似乎没有考虑条件表达式
【发布时间】:2021-05-15 05:45:45
【问题描述】:

这是我第一次使用 DynamoDB,并在我的系统中为用户帐户创建了一个表。

表定义如下:

{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "AccountId",
                "AttributeType": "B"
            },
            {
                "AttributeName": "Email",
                "AttributeType": "S"
            }
        ],
        "KeySchema": [
            {
                "AttributeName": "AccountId",
                "KeyType": "HASH"
            }
        ],
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "EmailAddress",
                "KeySchema": [
                    {
                        "AttributeName": "Email",
                        "KeyType": "HASH"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE"
            }
        ]
    }
}

为简洁起见,省略了一些字段。

我正在使用 Rusoto DynamoDB 客户端,这就是 PutItem 调用的样子:

dynamodb_client.put_item(PutItemInput{
    item: account_doc.as_hashmap(),
    table_name: accounts_datastore_name,
    condition_expression: Some("attribute_not_exists(Email) and attribute_not_exists(AccountId)".to_string()),
    ..PutItemInput::default()
});

据我了解,这应该具有以下行为:如果有文档包含 Email 和我在新文档中提供的值或 AccountId 的值我是在新文档中提供。

我已经能够多次提交同一个文档,而服务没有任何错误。文件都在表格中。

知道为什么这个条件表达式允许文档通过吗?

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    您误解了条件的作用。它不查看表中的其他记录,只查看您是putting 的记录。想象一下以下两条记录:

    {
      "AccountId": "<some_unique_id_1>",
      "Email": "user@example.com"
    }
    

    {
      "AccountId": "<some_unique_id_2>",
      "Email": "user@example.com"
    }
    

    因为AccountId 的值不同,它们中的每一个都将被保存,这意味着它是表中的不同记录。

    您的情况会阻止您再次使用相同的AccountId 写入记录。因为AccountId 是记录的关键,并且您要确保正在写入的记录没有设置AccountId,所以只有第一次写入时才能写入记录。在这种情况下,条件的Email 部分实际上没有做任何事情。

    您可以根据需要考虑两种选择。

    1. 将密钥切换为电子邮件地址。这将确保电子邮件地址是唯一的。
    2. 使用transaction 写入您的记录。这并不像听起来那么简单。 Alex DeBrie has a pretty good article 关于使用交易。

    【讨论】:

    • 您的情况会阻止您再次使用相同的 AccountId 写入记录 我不明白这是为什么。我在我的条件中指定了 AccountIdEmail 字段。
    • 在这种情况下,条件的电子邮件部分实际上没有做任何事情。这是为什么?我能以某种方式利用 Email 被添加到 GSI 中的事实吗?
    • 它没有做任何事情的原因是因为如果AccountId 存在你不能把记录,但如果AccountId 不存在那么Email 也不能,因为AccountId 是钥匙。您无法利用 GS​​I,因为 GSI 中的密钥不是唯一的。
    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多