diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index df8c89b72..5b1992cdc 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -203,6 +203,9 @@ class Item(BaseModel): last_val = self.attrs[attr].value for key_part in key_parts[:-1]: + list_index_update = re.match('(.+)\\[([0-9]+)\\]', key_part) + if list_index_update: + key_part = list_index_update.group(1) # listattr[1] ==> listattr # Hack but it'll do, traverses into a dict last_val_type = list(last_val.keys()) if last_val_type and last_val_type[0] == 'M': @@ -212,6 +215,8 @@ class Item(BaseModel): last_val[key_part] = {'M': {}} last_val = last_val[key_part] + if list_index_update: + last_val = last_val['L'][int(list_index_update.group(2))] last_val_type = list(last_val.keys()) list_index_update = re.match('(.+)\\[([0-9]+)\\]', key_parts[-1]) diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index 356be7817..b4fb5e8c8 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -2361,7 +2361,6 @@ def test_update_list_index__set_index_of_a_string(): UpdateExpression='set itemstr[1]=:Item', ExpressionAttributeValues={':Item': {'S': 'string_update'}}) result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo2'}})['Item'] - print(result) ex.exception.response['Error']['Code'].should.equal('ValidationException') ex.exception.response['Error']['Message'].should.equal( @@ -2392,6 +2391,26 @@ def test_remove_list_index__remove_existing_nested_index(): assert result['itemmap']['M']['itemlist']['L'] == [{'S': 'bar1'}] +@mock_dynamodb2 +def test_remove_list_index__remove_existing_double_nested_index(): + table_name = 'test_list_index_access' + client = create_table_with_list(table_name) + client.put_item(TableName=table_name, + Item={'id': {'S': 'foo2'}, + 'itemmap': {'M': {'itemlist': {'L': [{'M': {'foo00': {'S': 'bar1'}, + 'foo01': {'S': 'bar2'}}}, + {'M': {'foo10': {'S': 'bar1'}, + 'foo11': {'S': 'bar2'}}}]}}}}) + client.update_item(TableName=table_name, Key={'id': {'S': 'foo2'}}, + UpdateExpression='REMOVE itemmap.itemlist[1].foo10') + # + result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo2'}})['Item'] + assert result['id'] == {'S': 'foo2'} + assert result['itemmap']['M']['itemlist']['L'][0]['M'].should.equal({'foo00': {'S': 'bar1'}, + 'foo01': {'S': 'bar2'}}) # untouched + assert result['itemmap']['M']['itemlist']['L'][1]['M'].should.equal({'foo11': {'S': 'bar2'}}) # changed + + @mock_dynamodb2 def test_remove_list_index__remove_index_out_of_range(): table_name = 'test_list_index_access'