Почему следующая запись DynamoDB с условным выражением завершается успешно? - PullRequest
1 голос
/ 30 апреля 2020

У меня есть следующий код для создания таблицы 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

Затем я использую его для создания двух объектов put:

    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 должен потерпеть неудачу, верно?

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Проверка состояния для PutItem не проверяет условие по произвольным элементам. Он проверяет условие только для элемента с одинаковым первичным ключом (ha sh и ключами сортировки), если такой элемент существует.

В вашем случае значение ключа сортировки отличается, поэтому, когда вы помещаете второй элемент, DynamoDB видит, что элемент no не существует с этим ключом, поэтому атрибут PK делает не существует.

По этой же причине проверка условия завершается неудачно при втором запуске кода - потому что в этот момент у вас уже есть элемент с таким же ha sh и ключи сортировки.

0 голосов
/ 30 апреля 2020

«IOPS» DynamoDB очень низок, и фактическая запись занимает некоторое время. Вы можете прочитать больше об этом здесь . Но если вы запустите код второй раз вскоре после этого, вы увидите, что получите ожидаемое botocore.errorfactory.ConditionalCheckFailedException.

Если я могу сослаться на то, что, по-вашему, вы пытаетесь сделать, - смоделируйте БД + данные. Если вы хотите издеваться над таким «дорогим» ресурсом, создайте настоящий фальшивый класс. Вы захотите обернуть все ваши обращения к БД в реальном коде каким-то модулем dal.py, который объединяет такие операции, как запись / чтение / et c. Затем вы высмеиваете эти методы / функции.
Вы не хотите писать код, тесно связанный с выбранной БД.

Лучшая практика заключается в использовании среды ORM, такой как SQLAlchemy. Это неоценимое время, чтобы изучить его. Но у вас могут быть ограничения по времени, о которых я не знаю.

...