Merge pull request #1675 from william-richard/dynamodb-index-query-bug-fix

Make dynamodb table indexes a list
This commit is contained in:
Steve Pulec 2018-06-08 18:46:41 -04:00 committed by GitHub
commit 0dfe55fde9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 5 deletions

View File

@ -706,7 +706,9 @@ class DynamoDBBackend(BaseBackend):
gsis_by_name[gsi_to_create['IndexName']] = gsi_to_create
table.global_indexes = gsis_by_name.values()
# in python 3.6, dict.values() returns a dict_values object, but we expect it to be a list in other
# parts of the codebase
table.global_indexes = list(gsis_by_name.values())
return table
def put_item(self, table_name, item_attrs, expected=None, overwrite=False):

View File

@ -1,17 +1,17 @@
from __future__ import unicode_literals, print_function
from decimal import Decimal
import six
import boto
import boto3
from boto3.dynamodb.conditions import Attr
from boto3.dynamodb.conditions import Attr, Key
import sure # noqa
import requests
from pytest import raises
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
from moto.dynamodb2 import dynamodb_backend2
from boto.exception import JSONResponseError
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key
from tests.helpers import requires_boto_gte
import tests.backport_assert_raises
@ -1119,7 +1119,7 @@ def test_update_item_on_map():
})
# Test nested value for a nonexistent attribute.
with raises(client.exceptions.ConditionalCheckFailedException):
with assert_raises(client.exceptions.ConditionalCheckFailedException):
table.update_item(Key={
'forum_name': 'the-key',
'subject': '123'
@ -1200,3 +1200,95 @@ def test_update_if_not_exists():
resp = table.scan()
# Still the original value
assert resp['Items'][0]['created_at'] == 123
@mock_dynamodb2
def test_query_global_secondary_index_when_created_via_update_table_resource():
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
# Create the DynamoDB table.
dynamodb.create_table(
TableName='users',
KeySchema=[
{
'AttributeName': 'user_id',
'KeyType': 'HASH'
},
],
AttributeDefinitions=[
{
'AttributeName': 'user_id',
'AttributeType': 'N',
},
{
'AttributeName': 'forum_name',
'AttributeType': 'S'
},
{
'AttributeName': 'subject',
'AttributeType': 'S'
},
],
ProvisionedThroughput={
'ReadCapacityUnits': 5,
'WriteCapacityUnits': 5
},
)
table = dynamodb.Table('users')
table.update(
AttributeDefinitions=[
{
'AttributeName': 'forum_name',
'AttributeType': 'S'
},
],
GlobalSecondaryIndexUpdates=[
{'Create':
{
'IndexName': 'forum_name_index',
'KeySchema': [
{
'AttributeName': 'forum_name',
'KeyType': 'HASH',
},
],
'Projection': {
'ProjectionType': 'ALL',
},
'ProvisionedThroughput': {
'ReadCapacityUnits': 5,
'WriteCapacityUnits': 5
},
}
}
]
)
next_user_id = 1
for my_forum_name in ['cats', 'dogs']:
for my_subject in ['my pet is the cutest', 'wow look at what my pet did', "don't you love my pet?"]:
table.put_item(Item={'user_id': next_user_id, 'forum_name': my_forum_name, 'subject': my_subject})
next_user_id += 1
# get all the cat users
forum_only_query_response = table.query(
IndexName='forum_name_index',
Select='ALL_ATTRIBUTES',
KeyConditionExpression=Key('forum_name').eq('cats'),
)
forum_only_items = forum_only_query_response['Items']
assert len(forum_only_items) == 3
for item in forum_only_items:
assert item['forum_name'] == 'cats'
# query all cat users with a particular subject
forum_and_subject_query_results = table.query(
IndexName='forum_name_index',
Select='ALL_ATTRIBUTES',
KeyConditionExpression=Key('forum_name').eq('cats'),
FilterExpression=Attr('subject').eq('my pet is the cutest'),
)
forum_and_subject_items = forum_and_subject_query_results['Items']
assert len(forum_and_subject_items) == 1
assert forum_and_subject_items[0] == {'user_id': Decimal('1'), 'forum_name': 'cats',
'subject': 'my pet is the cutest'}