def parse_attribute_updates(cls, attribute_updates_json): attribute_updates = {} attribute_updates_json = attribute_updates_json or {} for attr, attr_update_json in attribute_updates_json.iteritems(): action_type = attr_update_json[Props.ACTION] if action_type == Values.ACTION_TYPE_ADD: action = models.UpdateItemAction.UPDATE_ACTION_ADD elif action_type == Values.ACTION_TYPE_DELETE: action = models.UpdateItemAction.UPDATE_ACTION_DELETE elif action_type == Values.ACTION_TYPE_PUT: action = models.UpdateItemAction.UPDATE_ACTION_PUT dynamodb_value = attr_update_json[Props.VALUE] assert len(dynamodb_value) == 1 (dynamodb_attr_type, dynamodb_attr_value) = ( dynamodb_value.items()[0] ) value = cls.decode_attr_value( dynamodb_attr_type, dynamodb_attr_value) update_action = models.UpdateItemAction(action, value) attribute_updates[attr] = update_action return attribute_updates
def parse_attribute_updates(cls, attribute_updates_json): attribute_updates = {} for attr, attr_update_json in attribute_updates_json.iteritems(): validation.validate_attr_name(attr) validation.validate_object(attr_update_json, attr) action_type_json = attr_update_json.pop(Props.ACTION, None) validation.validate_string(action_type_json, Props.ACTION) value_json = attr_update_json.pop(Props.VALUE, None) if value_json: validation.validate_object(value_json, Props.VALUE) value = cls.parse_typed_attr_value(value_json) else: value = None update_action = models.UpdateItemAction(action_type_json, value) validation.validate_unexpected_props(attr_update_json, attr) attribute_updates[attr] = update_action return attribute_updates
def test_update_item_add_number(self, mock_select_item): mock_execute_query = mock.Mock(return_value=[{'[applied]': True}]) mock_table_schema = models.TableSchema( key_attributes=['hash_key', 'range_key'], attribute_type_map={'hash_key': None, 'range_key': None, 'ViewsCount': None}, index_def_map=None ) driver = self.get_connection(mock_execute_query, mock_table_schema) def make_select_result(i): value = models.AttributeValue('N', i) return mock.Mock(items=[{'ViewsCount': value}]) values = [make_select_result(i) for i in range(10)] mock_select_item.side_effect = values context = mock.Mock(tenant='fake_tenant') table_info = mock.Mock( schema=mock_table_schema, internal_name='"u_fake_tenant"."u_fake_table"' ) key_attrs = { 'hash_key': models.AttributeValue('N', 1), 'range_key': models.AttributeValue('S', 'two') } attr_actions = { 'ViewsCount': models.UpdateItemAction( models.UpdateItemAction.UPDATE_ACTION_ADD, models.AttributeValue('N', 1) ) } for i in range(10): driver.update_item(context, table_info, key_attrs, attr_actions) expected_calls = [ mock.call('UPDATE "u_fake_tenant"."u_fake_table" SET ' '"u_ViewsCount"=%d WHERE "u_hash_key"=1 AND ' '"u_range_key"=\'two\' ' 'IF "u_ViewsCount"=%d' % (i, i - 1), consistent=True) for i in range(1, 11) ] self.assertEqual(expected_calls, mock_execute_query.mock_calls)
def test_update_item_delete_set(self, mock_select_item): mock_execute_query = mock.Mock(return_value=None) mock_table_schema = TableSchema( key_attributes=['hash_key', 'range_key'], attribute_type_map={ 'hash_key': None, 'range_key': None, 'Tags': None }, index_def_map=None) driver = self.get_connection(mock_execute_query, mock_table_schema) value = models.AttributeValue('SS', {"Update", "Help"}) mock_select_item.return_value = mock.Mock(items=[{'Tags': value}]) context = mock.Mock(tenant='fake_tenant') table_info = mock.Mock(schema=mock_table_schema, internal_name='"u_fake_tenant"."u_fake_table"') key_attrs = { 'hash_key': models.AttributeValue('N', 1), 'range_key': models.AttributeValue('S', 'two') } attr_actions = { 'Tags': models.UpdateItemAction( models.UpdateItemAction.UPDATE_ACTION_DELETE, models.AttributeValue('SS', {"Update"})) } driver.update_item(context, table_info, key_attrs, attr_actions) expected_calls = [ mock.call( 'UPDATE "u_fake_tenant"."u_fake_table" SET ' '"u_Tags"={\'Help\'} WHERE "u_hash_key"=1 AND ' '"u_range_key"=\'two\' ' 'IF "u_Tags"={\'Help\',\'Update\'}', consistent=True) ] self.assertEqual(expected_calls, mock_execute_query.mock_calls)