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}}
The item in the table is not updated and an Error (ConditionalCheckFailedException) is thrown
The item is updated
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)
https://github.com/spulec/moto/blob/1.3.6/moto/dynamodb2/responses.py#L196
Is this support 'OR' expression?
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,