Moto: dynamodb2 ConditionExpression does not work

Created on 20 Apr 2018  路  11Comments  路  Source: spulec/moto

Reproduce the bug:

I am doing the following in ipython:

Setup moto:

import moto
import boto3
mock = moto.mock_dynamodb2()
mock.start()

Create a table:

client = boto3.client("dynamodb")
client.create_table(TableName="test"
    , KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}]
    , AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}]
    , ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1})

Insert some data:

table = boto3.resource("dynamodb").Table("test")
table.put_item(Item={"id": "abc", "task_states": {"task_id": {"phase": "ABSENT"}}})

Now I want to update the item, with a failing condition:

table.update_item(Key={"id": "abc"}
    , UpdateExpression="SET task_states.task_id.phase = :p"
    , ExpressionAttributeValues={":p": "DELETED", ":v1": "FINISHED", ":v2": "RUNNING"}
    , ConditionExpression="task_states.task_id.phase IN (:v1,:v2)")
Out[16]:
{'Attributes': {'id': 'abc', 'task_states': {'task_id': {'phase': 'DELETED'}}},
 'ConsumedCapacity': {'CapacityUnits': 0.5, 'TableName': 'test'},
 'ResponseMetadata': {'HTTPHeaders': {'Content-Type': 'text/plain',
   'server': 'amazon.com',
   'x-amzn-requestid': 'UIDN2VKJWO9W59LQYWN8CMQCOA321AXHSDXV7E3J6JW9ZL0E8IHY'},
  'HTTPStatusCode': 200,
  'RequestId': 'UIDN2VKJWO9W59LQYWN8CMQCOA321AXHSDXV7E3J6JW9ZL0E8IHY',
  'RetryAttempts': 0}}

Expected Result:

The item in the table is not updated and an Error (ConditionalCheckFailedException) is thrown

Actual Result

The item is updated

bug

All 11 comments

I'm seeing the same issue with a simple ConditionExpression="id = :id" in the update_item call.

Thanks for opening; will file this as a bug.

Hi - I'm still experiencing this bug with the update_item call - is there any update yet?
thanks -

No progress I'm aware of. We are a bit swamped right now and could use help from anyone with some knowledge of this.

Conditions on PutItem also seem to fail (e.g attribute_not_exists)

ConditionExpression=Attr("email").not_exists(), as another example. #1071 seems to have another variant. I'm guessing ConditionalExpression is just basically unimplemented. Hope someone has time to hack at this!

I think this was solved for me in #2266

Awesome! I'm going to close. If this is still broken for someone else, let me know.

Just hit an issue when deleting an item that doesn't exist with a ConditionExpression, was expecting an exception, but got a 200 response.

File: test_bug.py

import pytest
import json
import boto3
from moto import mock_dynamodb2

@pytest.fixture
def dynamodb_mock():
table_name = 'unittest'

mock = mock_dynamodb2()
mock.start()

dynamodb = boto3.resource('dynamodb', region_name='eu-west-1')

table = dynamodb.create_table(
        TableName=table_name,
        KeySchema=[
            {
                'AttributeName': 'userId',
                'KeyType': 'HASH'
            },
            {
                'AttributeName': 'noteId',
                'KeyType': 'RANGE'
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'userId',
                'AttributeType': 'S'
            },
            {
                'AttributeName': 'noteId',
                'AttributeType': 'S'
            }
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 5,
            'WriteCapacityUnits': 5
        }
    )

### Add item
item = {
    'userId': '123456789012',
    'noteId': '1234abcd',
}

table.put_item(TableName=table_name, Item=item)

# Delete item that doesn't exist.  THIS SHOULD FAIL.
key = {
    'userId': '123456789012',
    'noteId': '1234abc'
}

response = table.delete_item(
    TableName='unittest',
    Key=key,
    ConditionExpression="noteId = :noteId",
    ExpressionAttributeValues={":noteId": '1234abc'}
)

print("response: " + json.dumps(response))

yield
# teardown: stop moto server
mock.stop()

def test_delete_item(dynamodb_mock):
assert 2 == 2

Execute test: pytest test_bug.py -s
...
tests/test_bug.py response: {"Attributes": {}, "ResponseMetadata": {"RequestId": "DIYMIN5AQMJ2L4J1VYDY6M25RQ0AX2GAFX3P90RWNWNIAP6LYES8", "HTTPStatusCode": 200, "HTTPHeaders": {"server": "amazon.com", "x-amzn-requestid": "DIYMIN5AQMJ2L4J1VYDY6M25RQ0AX2GAFX3P90RWNWNIAP6LYES8"}, "RetryAttempts": 0}}
...

$ pip show moto
Name: moto
Version: 1.3.13

Ran into exactly the same bug today as well as @Alex-Burgess reported a couple of weeks ago,

Was this page helpful?
0 / 5 - 0 ratings