【问题标题】:Why does the following dynamoDB write with conditional expression succeeds?为什么以下 dynamoDB 使用条件表达式写入成功?
【发布时间】:2020-04-30 15:40:30
【问题描述】:

我有以下代码来创建一个 dynamoDB 表:

def create_mock_dynamo_table():
    conn = boto3.client(
        "dynamodb",
        region_name=REGION,
        aws_access_key_id="ak",
        aws_secret_access_key="sk",
    )
    conn.create_table(
        TableName=DYNAMO_DB_TABLE,
        KeySchema=[
            {'AttributeName': 'PK', 'KeyType': 'HASH'},
            {'AttributeName': 'SK', 'KeyType': 'RANGE'}
        ],
        AttributeDefinitions=[
            {'AttributeName': 'PK', 'AttributeType': 'S'},
            {'AttributeName': 'SK', 'AttributeType': 'S'}],
        ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
    )
    mock_table = boto3.resource('dynamodb', region_name=REGION).Table(DYNAMO_DB_TABLE)
    return mock_table

然后我用它来创建两个放置项:

    mock_table = create_mock_dynamo_table()
    mock_table.put_item(
        Item={
            'PK': 'did:100000001',
            'SK': 'weekday:monday:start_time:00:30',
        }
    )
    mock_table.put_item(
        Item={
            'PK': 'did:100000001',
            'SK': 'weekday:monday:start_time:00:40',
        },
        ConditionExpression='attribute_not_exists(PK)'
    )

当我执行第二个put_item 时,PK 已经存在于系统中,只有排序键不同。但是我设置的条件只存在于相同的PK 中。那么第二个put_item 应该会失败吧?

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb boto3 amazon-dynamodb-index


    【解决方案1】:

    PutItem 的条件检查不会针对任意项检查条件。它仅针对具有相同主键(散列和排序键)的项目检查条件,如果这样的项目存在的话。

    在您的情况下,排序键的值不同,因此当您放置第二个项目时,DynamoDB 看到 no 项目与该键存在,因此 PK 属性不存在.

    这也是第二次运行代码时条件检查失败的原因——因为此时您已经拥有具有相同哈希和排序键的项目。

    【讨论】:

      【解决方案2】:

      DynamoDB 的“IOPS”非常低,实际写入需要一些时间。你可以阅读更多关于它的信息here。但是,如果您稍后再次运行该代码,您会看到您将获得预期的botocore.errorfactory.ConditionalCheckFailedException

      如果我可以参考我认为您正在尝试做的事情 - 模拟数据库 + 数据。当你想模拟这样一个“昂贵”的资源时,制作一个真正的假类。您需要使用某种dal.py 模块将所有数据库访问包装在实际代码中,该模块整合了诸如写入/读取/等操作。然后,您模拟这些方法/函数。
      您不想编写与所选数据库紧密耦合的代码。

      最佳实践是使用 ORM 框架,例如 SQLAlchemy。现在花时间学习它是非常宝贵的。但是,您可能有我不知道的时间限制。

      【讨论】:

      • 我认为您关于延迟的推理是错误的。首先,我确实在真正的 dynamoDB 中尝试过,几秒钟后它就会一直工作。 (我从笔记本上复制了片段)。其次,我也通过 moto 尝试过。第三,后来我得到了这个问题:stackoverflow.com/questions/32833351/… 这说明,条件 put 将首先搜索具有给定哈希和范围的项目。由于数据库中不存在哈希和范围组合,我在第二次写入时的情况变得微不足道true
      • @SouravSarkar 我是正确的,然后,干杯。我进行了一次糟糕的测试并得出了错误的结论,虽然我怀疑密钥总是成对地被隐式处理,但只是找不到任何文档来支持它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2015-05-13
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      相关资源
      最近更新 更多