Better error messaging for dynamodb table gets for range key tables without range keys used. cc #28

This commit is contained in:
Steve Pulec 2013-05-16 22:24:26 -04:00
parent 755fe6563b
commit 549cb23b7f
3 changed files with 41 additions and 6 deletions

View File

@ -101,6 +101,10 @@ class Table(object):
self.created_at = datetime.datetime.now()
self.items = defaultdict(dict)
@property
def has_range_key(self):
return self.range_key_attr is not None
@property
def describe(self):
results = {
@ -122,7 +126,7 @@ class Table(object):
"TableSizeBytes": 0,
}
}
if self.range_key_attr:
if self.has_range_key:
results["Table"]["KeySchema"]["RangeKeyElement"] = {
"AttributeName": self.range_key_attr,
"AttributeType": self.range_key_type
@ -132,7 +136,7 @@ class Table(object):
def __len__(self):
count = 0
for key, value in self.items.iteritems():
if self.range_key_attr:
if self.has_range_key:
count += len(value)
else:
count += 1
@ -143,7 +147,7 @@ class Table(object):
def put_item(self, item_attrs):
hash_value = DynamoType(item_attrs.get(self.hash_key_attr))
if self.range_key_attr:
if self.has_range_key:
range_value = DynamoType(item_attrs.get(self.range_key_attr))
else:
range_value = None
@ -157,6 +161,8 @@ class Table(object):
return item
def get_item(self, hash_key, range_key):
if self.has_range_key and not range_key:
raise ValueError("Table has a range key, but no range key was passed into get_item")
try:
if range_key:
return self.items[hash_key][range_key]

View File

@ -188,12 +188,17 @@ class DynamoHandler(BaseResponse):
hash_key = key['HashKeyElement']
range_key = key.get('RangeKeyElement')
attrs_to_get = self.body.get('AttributesToGet')
try:
item = dynamodb_backend.get_item(name, hash_key, range_key)
except ValueError:
er = 'com.amazon.coral.validate#ValidationException'
return self.error(er, status=400)
if item:
item_dict = item.describe_attrs(attrs_to_get)
item_dict['ConsumedCapacityUnits'] = 0.5
return dynamo_json_dump(item_dict)
else:
# Item not found
er = 'com.amazonaws.dynamodb.v20111205#ResourceNotFoundException'
return self.error(er, status=404)

View File

@ -6,7 +6,7 @@ from moto import mock_dynamodb
from moto.dynamodb import dynamodb_backend
from boto.dynamodb import condition
from boto.dynamodb.exceptions import DynamoDBKeyNotFoundError
from boto.dynamodb.exceptions import DynamoDBKeyNotFoundError, DynamoDBValidationError
from boto.exception import DynamoDBResponseError
@ -154,7 +154,7 @@ def test_get_missing_item():
hash_key='tester',
range_key='other',
).should.throw(DynamoDBKeyNotFoundError)
table.has_item("foobar").should.equal(False)
table.has_item("foobar", "more").should.equal(False)
@mock_dynamodb
@ -170,6 +170,30 @@ def test_get_item_with_undeclared_table():
).should.throw(DynamoDBKeyNotFoundError)
@mock_dynamodb
def test_get_item_without_range_key():
conn = boto.connect_dynamodb()
message_table_schema = conn.create_schema(
hash_key_name="test_hash",
hash_key_proto_value=int,
range_key_name="test_range",
range_key_proto_value=int,
)
table = conn.create_table(
name='messages',
schema=message_table_schema,
read_units=10,
write_units=10
)
hash_key = 3241526475
range_key = 1234567890987
new_item = table.new_item(hash_key=hash_key, range_key=range_key)
new_item.put()
table.get_item.when.called_with(hash_key=hash_key).should.throw(DynamoDBValidationError)
@mock_dynamodb
def test_delete_item():
conn = boto.connect_dynamodb()