Merge pull request #509 from im-auld/Bug-Fix-Secondary-Indexes-Ignored

Bug fix secondary indexes ignored
This commit is contained in:
Steve Pulec 2016-01-17 15:38:19 -05:00
commit 7e4e9b23ad
4 changed files with 94 additions and 2 deletions

View File

@ -184,6 +184,7 @@ class Table(object):
'ItemCount': len(self), 'ItemCount': len(self),
'CreationDateTime': unix_time(self.created_at), 'CreationDateTime': unix_time(self.created_at),
'GlobalSecondaryIndexes': [index for index in self.global_indexes], 'GlobalSecondaryIndexes': [index for index in self.global_indexes],
'LocalSecondaryIndexes': [index for index in self.indexes]
} }
} }
return results return results

View File

@ -100,12 +100,14 @@ class DynamoHandler(BaseResponse):
attr = body["AttributeDefinitions"] attr = body["AttributeDefinitions"]
# getting the indexes # getting the indexes
global_indexes = body.get("GlobalSecondaryIndexes", []) global_indexes = body.get("GlobalSecondaryIndexes", [])
local_secondary_indexes = body.get("LocalSecondaryIndexes", [])
table = dynamodb_backend2.create_table(table_name, table = dynamodb_backend2.create_table(table_name,
schema=key_schema, schema=key_schema,
throughput=throughput, throughput=throughput,
attr=attr, attr=attr,
global_indexes=global_indexes) global_indexes=global_indexes,
indexes=local_secondary_indexes)
if table is not None: if table is not None:
return dynamo_json_dump(table.describe) return dynamo_json_dump(table.describe)
else: else:

View File

@ -11,8 +11,9 @@ from moto import mock_dynamodb2
from boto.exception import JSONResponseError from boto.exception import JSONResponseError
from tests.helpers import requires_boto_gte from tests.helpers import requires_boto_gte
try: try:
from boto.dynamodb2.fields import GlobalAllIndex, HashKey, RangeKey from boto.dynamodb2.fields import GlobalAllIndex, HashKey, RangeKey, AllIndex
from boto.dynamodb2.table import Item, Table from boto.dynamodb2.table import Item, Table
from boto.dynamodb2.types import STRING, NUMBER
from boto.dynamodb2.exceptions import ValidationException from boto.dynamodb2.exceptions import ValidationException
from boto.dynamodb2.exceptions import ConditionalCheckFailedException from boto.dynamodb2.exceptions import ConditionalCheckFailedException
except ImportError: except ImportError:
@ -30,6 +31,30 @@ def create_table():
return table return table
def create_table_with_local_indexes():
table = Table.create(
'messages',
schema=[
HashKey('forum_name'),
RangeKey('subject'),
],
throughput={
'read': 10,
'write': 10,
},
indexes=[
AllIndex(
'threads_index',
parts=[
HashKey('forum_name', data_type=STRING),
RangeKey('threads', data_type=NUMBER),
]
)
]
)
return table
def iterate_results(res): def iterate_results(res):
for i in res: for i in res:
pass pass
@ -56,6 +81,7 @@ def test_create_table():
{'KeyType': 'HASH', 'AttributeName': 'forum_name'}, {'KeyType': 'HASH', 'AttributeName': 'forum_name'},
{'KeyType': 'RANGE', 'AttributeName': 'subject'} {'KeyType': 'RANGE', 'AttributeName': 'subject'}
], ],
'LocalSecondaryIndexes': [],
'ItemCount': 0, 'CreationDateTime': 1326499200.0, 'ItemCount': 0, 'CreationDateTime': 1326499200.0,
'GlobalSecondaryIndexes': [], 'GlobalSecondaryIndexes': [],
} }
@ -63,6 +89,48 @@ def test_create_table():
table.describe().should.equal(expected) table.describe().should.equal(expected)
@requires_boto_gte("2.9")
@mock_dynamodb2
@freeze_time("2012-01-14")
def test_create_table_with_local_index():
table = create_table_with_local_indexes()
expected = {
'Table': {
'AttributeDefinitions': [
{'AttributeName': 'forum_name', 'AttributeType': 'S'},
{'AttributeName': 'subject', 'AttributeType': 'S'},
{'AttributeName': 'threads', 'AttributeType': 'N'}
],
'ProvisionedThroughput': {
'NumberOfDecreasesToday': 0,
'WriteCapacityUnits': 10,
'ReadCapacityUnits': 10,
},
'TableSizeBytes': 0,
'TableName': 'messages',
'TableStatus': 'ACTIVE',
'KeySchema': [
{'KeyType': 'HASH', 'AttributeName': 'forum_name'},
{'KeyType': 'RANGE', 'AttributeName': 'subject'}
],
'LocalSecondaryIndexes': [
{
'IndexName': 'threads_index',
'KeySchema': [
{'AttributeName': 'forum_name', 'KeyType': 'HASH'},
{'AttributeName': 'threads', 'KeyType': 'RANGE'}
],
'Projection': {'ProjectionType': 'ALL'}
}
],
'ItemCount': 0,
'CreationDateTime': 1326499200.0,
'GlobalSecondaryIndexes': [],
}
}
table.describe().should.equal(expected)
@requires_boto_gte("2.9") @requires_boto_gte("2.9")
@mock_dynamodb2 @mock_dynamodb2
def test_delete_table(): def test_delete_table():
@ -570,6 +638,26 @@ def test_query_with_global_indexes():
list(results).should.have.length_of(0) list(results).should.have.length_of(0)
@mock_dynamodb2
def test_query_with_local_indexes():
table = create_table_with_local_indexes()
item_data = {
'forum_name': 'Cool Forum',
'subject': 'Check this out!',
'version': '1',
'threads': 1,
'status': 'inactive'
}
item = Item(table, item_data)
item.save(overwrite=True)
item['version'] = '2'
item.save(overwrite=True)
# Revisit this query once support for QueryFilter is added
results = table.query(forum_name__eq='Cool Forum', index='threads_index')
list(results).should.have.length_of(1)
@mock_dynamodb2 @mock_dynamodb2
def test_reverse_query(): def test_reverse_query():
conn = boto.dynamodb2.layer1.DynamoDBConnection() conn = boto.dynamodb2.layer1.DynamoDBConnection()

View File

@ -48,6 +48,7 @@ def test_create_table():
], ],
'ItemCount': 0, 'CreationDateTime': 1326499200.0, 'ItemCount': 0, 'CreationDateTime': 1326499200.0,
'GlobalSecondaryIndexes': [], 'GlobalSecondaryIndexes': [],
'LocalSecondaryIndexes': []
} }
} }
conn = boto.dynamodb2.connect_to_region( conn = boto.dynamodb2.connect_to_region(