Adds the ConditionalCheckFailedException to put_item
If the Item‘s original data is inconsistent with what's in DynamoDB, the request should fail (unless overwrite is set to True). http://boto.readthedocs.org/en/latest/ref/dynamodb2.html#boto.dynamodb2.table.Table.put_item
This commit is contained in:
parent
abb3357925
commit
e3c859868c
@ -191,7 +191,7 @@ class Table(object):
|
|||||||
keys.append(key['AttributeName'])
|
keys.append(key['AttributeName'])
|
||||||
return keys
|
return keys
|
||||||
|
|
||||||
def put_item(self, item_attrs):
|
def put_item(self, item_attrs, expected = None, overwrite = False):
|
||||||
hash_value = DynamoType(item_attrs.get(self.hash_key_attr))
|
hash_value = DynamoType(item_attrs.get(self.hash_key_attr))
|
||||||
if self.has_range_key:
|
if self.has_range_key:
|
||||||
range_value = DynamoType(item_attrs.get(self.range_key_attr))
|
range_value = DynamoType(item_attrs.get(self.range_key_attr))
|
||||||
@ -200,6 +200,35 @@ class Table(object):
|
|||||||
|
|
||||||
item = Item(hash_value, self.hash_key_type, range_value, self.range_key_type, item_attrs)
|
item = Item(hash_value, self.hash_key_type, range_value, self.range_key_type, item_attrs)
|
||||||
|
|
||||||
|
if not overwrite:
|
||||||
|
if expected is None:
|
||||||
|
expected = {}
|
||||||
|
lookup_range_value = range_value
|
||||||
|
else:
|
||||||
|
expected_range_value = expected.get(self.range_key_attr, {}).get("Value")
|
||||||
|
if(expected_range_value is None):
|
||||||
|
lookup_range_value = range_value
|
||||||
|
else:
|
||||||
|
lookup_range_value = DynamoType(expected_range_value)
|
||||||
|
|
||||||
|
current = self.get_item(hash_value, lookup_range_value)
|
||||||
|
|
||||||
|
if current is None:
|
||||||
|
current_attr = {}
|
||||||
|
elif hasattr(current,'attrs'):
|
||||||
|
current_attr = current.attrs
|
||||||
|
else:
|
||||||
|
current_attr = current
|
||||||
|
|
||||||
|
for key, val in expected.iteritems():
|
||||||
|
if 'Exists' in val and val['Exists'] == False:
|
||||||
|
if key in current_attr:
|
||||||
|
raise ValueError("The conditional request failed")
|
||||||
|
elif key not in current_attr:
|
||||||
|
raise ValueError("The conditional request failed")
|
||||||
|
elif DynamoType(val['Value']).value != current_attr[key].value:
|
||||||
|
raise ValueError("The conditional request failed")
|
||||||
|
|
||||||
if range_value:
|
if range_value:
|
||||||
self.items[hash_value][range_value] = item
|
self.items[hash_value][range_value] = item
|
||||||
else:
|
else:
|
||||||
@ -317,11 +346,11 @@ class DynamoDBBackend(BaseBackend):
|
|||||||
table.throughput = throughput
|
table.throughput = throughput
|
||||||
return table
|
return table
|
||||||
|
|
||||||
def put_item(self, table_name, item_attrs):
|
def put_item(self, table_name, item_attrs, expected = None, overwrite = False):
|
||||||
table = self.tables.get(table_name)
|
table = self.tables.get(table_name)
|
||||||
if not table:
|
if not table:
|
||||||
return None
|
return None
|
||||||
return table.put_item(item_attrs)
|
return table.put_item(item_attrs, expected, overwrite)
|
||||||
|
|
||||||
def get_table_keys_name(self, table_name, keys):
|
def get_table_keys_name(self, table_name, keys):
|
||||||
"""
|
"""
|
||||||
|
@ -134,7 +134,17 @@ class DynamoHandler(BaseResponse):
|
|||||||
def put_item(self):
|
def put_item(self):
|
||||||
name = self.body['TableName']
|
name = self.body['TableName']
|
||||||
item = self.body['Item']
|
item = self.body['Item']
|
||||||
result = dynamodb_backend2.put_item(name, item)
|
overwrite = 'Expected' not in self.body
|
||||||
|
if not overwrite:
|
||||||
|
expected = self.body['Expected']
|
||||||
|
else:
|
||||||
|
expected = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = dynamodb_backend2.put_item(name, item, expected, overwrite)
|
||||||
|
except Exception:
|
||||||
|
er = 'com.amazonaws.dynamodb.v20111205#ConditionalCheckFailedException'
|
||||||
|
return self.error(er)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
item_dict = result.to_json()
|
item_dict = result.to_json()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user