Merge pull request #1627 from MauPalantir/support-nested
Support assignment of nested attributes if only the topmost value exists
This commit is contained in:
commit
e1c445ad3c
@ -176,16 +176,17 @@ class Item(BaseModel):
|
|||||||
key_parts = key.split('.')
|
key_parts = key.split('.')
|
||||||
attr = key_parts.pop(0)
|
attr = key_parts.pop(0)
|
||||||
if attr not in self.attrs:
|
if attr not in self.attrs:
|
||||||
raise ValueError()
|
raise ValueError
|
||||||
|
|
||||||
last_val = self.attrs[attr].value
|
last_val = self.attrs[attr].value
|
||||||
for key_part in key_parts:
|
for key_part in key_parts:
|
||||||
# Hack but it'll do, traverses into a dict
|
# Hack but it'll do, traverses into a dict
|
||||||
if list(last_val.keys())[0] == 'M':
|
last_val_type = list(last_val.keys())
|
||||||
last_val = last_val['M']
|
if last_val_type and last_val_type[0] == 'M':
|
||||||
|
last_val = last_val['M']
|
||||||
|
|
||||||
if key_part not in last_val:
|
if key_part not in last_val:
|
||||||
raise ValueError()
|
last_val[key_part] = {'M': {}}
|
||||||
|
|
||||||
last_val = last_val[key_part]
|
last_val = last_val[key_part]
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import boto3
|
|||||||
from boto3.dynamodb.conditions import Attr
|
from boto3.dynamodb.conditions import Attr
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
import requests
|
import requests
|
||||||
|
from pytest import raises
|
||||||
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
|
from moto import mock_dynamodb2, mock_dynamodb2_deprecated
|
||||||
from moto.dynamodb2 import dynamodb_backend2
|
from moto.dynamodb2 import dynamodb_backend2
|
||||||
from boto.exception import JSONResponseError
|
from boto.exception import JSONResponseError
|
||||||
@ -1052,6 +1053,7 @@ def test_query_missing_expr_names():
|
|||||||
@mock_dynamodb2
|
@mock_dynamodb2
|
||||||
def test_update_item_on_map():
|
def test_update_item_on_map():
|
||||||
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
|
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
|
||||||
|
client = boto3.client('dynamodb', region_name='us-east-1')
|
||||||
|
|
||||||
# Create the DynamoDB table.
|
# Create the DynamoDB table.
|
||||||
dynamodb.create_table(
|
dynamodb.create_table(
|
||||||
@ -1092,21 +1094,44 @@ def test_update_item_on_map():
|
|||||||
resp = table.scan()
|
resp = table.scan()
|
||||||
resp['Items'][0]['body'].should.equal({'nested': {'data': 'test'}})
|
resp['Items'][0]['body'].should.equal({'nested': {'data': 'test'}})
|
||||||
|
|
||||||
|
# Nonexistent nested attributes are supported for existing top-level attributes.
|
||||||
table.update_item(Key={
|
table.update_item(Key={
|
||||||
'forum_name': 'the-key',
|
'forum_name': 'the-key',
|
||||||
'subject': '123'
|
'subject': '123'
|
||||||
},
|
},
|
||||||
UpdateExpression='SET body.#nested.#data = :tb',
|
UpdateExpression='SET body.#nested.#data = :tb, body.nested.#nonexistentnested.#data = :tb2',
|
||||||
ExpressionAttributeNames={
|
ExpressionAttributeNames={
|
||||||
'#nested': 'nested',
|
'#nested': 'nested',
|
||||||
|
'#nonexistentnested': 'nonexistentnested',
|
||||||
'#data': 'data'
|
'#data': 'data'
|
||||||
},
|
},
|
||||||
ExpressionAttributeValues={
|
ExpressionAttributeValues={
|
||||||
':tb': 'new_value'
|
':tb': 'new_value',
|
||||||
|
':tb2': 'other_value'
|
||||||
})
|
})
|
||||||
|
|
||||||
resp = table.scan()
|
resp = table.scan()
|
||||||
resp['Items'][0]['body'].should.equal({'nested': {'data': 'new_value'}})
|
resp['Items'][0]['body'].should.equal({
|
||||||
|
'nested': {
|
||||||
|
'data': 'new_value',
|
||||||
|
'nonexistentnested': {'data': 'other_value'}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Test nested value for a nonexistent attribute.
|
||||||
|
with raises(client.exceptions.ConditionalCheckFailedException):
|
||||||
|
table.update_item(Key={
|
||||||
|
'forum_name': 'the-key',
|
||||||
|
'subject': '123'
|
||||||
|
},
|
||||||
|
UpdateExpression='SET nonexistent.#nested = :tb',
|
||||||
|
ExpressionAttributeNames={
|
||||||
|
'#nested': 'nested'
|
||||||
|
},
|
||||||
|
ExpressionAttributeValues={
|
||||||
|
':tb': 'new_value'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# https://github.com/spulec/moto/issues/1358
|
# https://github.com/spulec/moto/issues/1358
|
||||||
|
Loading…
Reference in New Issue
Block a user