def test_remove_multiple_basic_and_sophisticated_items_from_path_target( self): query_kwargs = {"id": "sampleIdTwo"} success_fields_set: bool = self.users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter( field_path='fieldToDelete', value_to_set="multipleBasicAndSophisticatedRemoval"), FieldSetter( field_path='sophisticatedRemoval.{{id}}.nestedVariable', query_kwargs=query_kwargs, value_to_set="nestedDude") ]) self.assertTrue(success_fields_set) deletion_response = self.users_table.delete_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'field': FieldRemover(field_path="fieldToDelete"), 'nested': FieldRemover( field_path="sophisticatedRemoval.{{id}}.nestedVariable", query_kwargs=query_kwargs) }) self.assertTrue(all(deletion_response.values()))
def test_remove_multiple_basic_and_sophisticated_items_from_path_target(self): query_kwargs = {"id": "sampleIdTwo"} success_fields_set = self.users_table.set_update_multiple_fields( key_name="accountId", key_value=self.test_account_id, setters=[ FieldSetter( target_path="fieldToRemove", value_to_set="multipleBasicAndSophisticatedRemoval" ), FieldSetter( target_path="sophisticatedRemoval.{{id}}.nestedVariable", query_kwargs=query_kwargs, value_to_set="nestedDude" ) ] ) self.assertTrue(success_fields_set) success_fields_remove = self.users_table.remove_multiple_items_at_path_targets( key_name="accountId", key_value=self.test_account_id, removers=[ FieldRemover(target_path="fieldToRemove"), FieldRemover(target_path="sophisticatedRemoval.{{id}}.nestedVariable", query_kwargs=query_kwargs) ] ) self.assertTrue(success_fields_remove)
def test_set_delete_multiple_fields(self: unittest.TestCase, users_table: DynamoDBCachingTable or ExternalDynamoDBApiCachingTable): users_table.clear_cached_data_and_pending_operations() random_field_value_one = random.randint(0, 100) random_field_value_two = random.randint(100, 200) update_success_one = users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete', value_to_set=random_field_value_one) self.assertTrue(update_success_one) update_success_two = users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete2', value_to_set=random_field_value_two) self.assertTrue(update_success_two) update_commit_success = users_table.commit_operations() self.assertTrue(update_commit_success) retrieved_data_one = users_table.get_field(key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete') self.assertEqual(retrieved_data_one['value'], random_field_value_one) retrieved_data_two = users_table.get_field(key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete2') self.assertEqual(retrieved_data_two['value'], random_field_value_two) multi_delete_response = users_table.delete_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path='fieldToDelete'), 'two': FieldRemover(field_path='fieldToDelete2') }) self.assertTrue(all(multi_delete_response.values())) retrieved_expected_empty_value_one_from_cache = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete') self.assertTrue(retrieved_expected_empty_value_one_from_cache['fromCache']) self.assertIsNone(retrieved_expected_empty_value_one_from_cache['value']) retrieved_expected_empty_value_two_from_cache = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete2') self.assertTrue(retrieved_expected_empty_value_two_from_cache['fromCache']) self.assertIsNone(retrieved_expected_empty_value_two_from_cache['value']) users_table.commit_operations() users_table.clear_cached_data_and_pending_operations() retrieved_expected_empty_value_one_from_database = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete') self.assertFalse( retrieved_expected_empty_value_one_from_database['fromCache']) self.assertIsNone( retrieved_expected_empty_value_one_from_database['value']) retrieved_expected_empty_value_two_from_database = users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='fieldToDelete2') self.assertFalse( retrieved_expected_empty_value_two_from_database['fromCache']) self.assertIsNone( retrieved_expected_empty_value_two_from_database['value'])
def test_deletion_and_removal_limit_size(self): class TableModel(TableDataModel): accountId = BaseField(field_type=str, required=True) container = BaseField(field_type=bool, required=False) table_model = TableModel() removers: Dict[str, FieldRemover] = dict() index = 0 while True: current_field_path = f"dummy{index}" removers[current_field_path] = FieldRemover(field_path=current_field_path) table_model.class_add_field( field_key=current_field_path, field_item=BaseField(field_type=bool, required=False) ) if getsizeof(removers) > (EXPRESSION_MAX_BYTES_SIZE * 1.5): break index += 1 users_table = PlaygroundDynamoDBBasicTable(data_model=table_model) # We initialize the table after having added all the fields to the class of the TableModel, so that # the indexing of the model will correctly be done on all the programmatically added fields. deletion_response = users_table.delete_multiple_fields(key_value=TEST_ACCOUNT_ID, removers=removers) self.assertTrue(all(deletion_response.values())) retrieved_removed_data = users_table.remove_multiple_fields(key_value=TEST_ACCOUNT_ID, removers=removers) self.assertIsNotNone(retrieved_removed_data)
def test_initialize_two_items_with_share_parents(self): base_field_path = 'containerForItemsWithSharedParents.{{itemId}}' item_name_field_path = f'{base_field_path}.itemName' potential_old_data_deletion_success = self.users_table.delete_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path=base_field_path, query_kwargs={'itemId': 'itemOne'}), 'two': FieldRemover(field_path=base_field_path, query_kwargs={'itemId': 'itemTwo'}) }) # We do not check the success of the deletion operation, because at the time of writing that, if a delete operation try to delete # a field path that does not exist, the operation will crash and return a success of False, where what we want is just to make sure # the data is fully clean so we can make sure we initialize the items from scratch. We do not really care about removing the data. update_success = self.users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path=item_name_field_path, query_kwargs={'itemId': 'itemOne'}, value_to_set="NameItemOne"), FieldSetter(field_path=item_name_field_path, query_kwargs={'itemId': 'itemTwo'}, value_to_set="NameItemTwo"), ]) self.assertTrue(update_success) retrieved_items_data = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path=base_field_path, query_kwargs={'itemId': 'itemOne'}), 'two': FieldGetter(field_path=base_field_path, query_kwargs={'itemId': 'itemTwo'}), }) self.assertIsNotNone(retrieved_items_data) self.assertEqual(retrieved_items_data.get('one', None), {'itemName': "NameItemOne"}) self.assertEqual(retrieved_items_data.get('two', None), {'itemName': "NameItemTwo"})
def test_remove_multiple_fields_with_multi_selectors(self): """ Removing multiple fields with a multi selector in single field_path in a remove_multiple_fields operation is awkward, because a single key per field_path can be assigned. Which means that the multiple fields retrieved with the multi selector must be send back in the same dictionary, like if it was a get_field with multi selectors. """ random_id = str(uuid4()) field_one_random = f"field_one_{uuid4()}" field_two_random = f"field_two_{uuid4()}" field_three_random = f"field_three_{uuid4()}" update_success = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='sophisticatedFieldToRemove.{{id}}', query_kwargs={'id': random_id}, value_to_set={ 'firstNestedValue': field_one_random, 'secondNestedValue': field_two_random, 'thirdNestedValue': field_three_random }) self.assertTrue(update_success) get_response_data = self.users_table.get_field( key_value=TEST_ACCOUNT_ID, query_kwargs={'id': random_id}, field_path= 'sophisticatedFieldToRemove.{{id}}.(firstNestedValue, secondNestedValue, thirdNestedValue)' ) self.assertEqual(get_response_data.get('firstNestedValue', None), field_one_random) self.assertEqual(get_response_data.get('secondNestedValue', None), field_two_random) self.assertEqual(get_response_data.get('thirdNestedValue', None), field_three_random) remove_response_data = self.users_table.remove_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover( field_path= 'sophisticatedFieldToRemove.{{id}}.(firstNestedValue, secondNestedValue)', query_kwargs={'id': random_id}) }) self.assertEqual( remove_response_data.get('one', {}).get('firstNestedValue', None), field_one_random) self.assertEqual( remove_response_data.get('one', {}).get('secondNestedValue', None), field_two_random) retrieved_third_value = self.users_table.get_field( key_value=TEST_ACCOUNT_ID, query_kwargs={'id': random_id}, field_path='sophisticatedFieldToRemove.{{id}}.thirdNestedValue') self.assertEqual(retrieved_third_value, field_three_random)
def test_remove_multiple_fields(self): random_id = str(uuid4()) random_value_one = f"one_{uuid4()}" random_value_two = f"two_{uuid4()}" update_success = self.users_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter(field_path='fieldToRemove', value_to_set=random_value_one), FieldSetter( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}, value_to_set=random_value_two) ]) self.assertTrue(update_success) get_response_data = self.users_table.get_multiple_fields( key_value=TEST_ACCOUNT_ID, getters={ 'one': FieldGetter(field_path='fieldToRemove'), 'two': FieldGetter( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}) }) self.assertEqual(get_response_data.get('one', None), random_value_one) self.assertEqual(get_response_data.get('two', None), random_value_two) remove_response_data = self.users_table.remove_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path='fieldToRemove'), 'two': FieldRemover( field_path= 'sophisticatedFieldToRemove.{{id}}.firstNestedValue', query_kwargs={'id': random_id}) }) print(remove_response_data)
def delete_attributes(self, user_id: str, attributes_keys: List[str]) -> Dict[str, bool]: deletion_successes: Dict[ str, bool] = self.table_client.delete_multiple_fields( key_value=user_id, removers={ key: FieldRemover(field_path=key) for key in attributes_keys }) return deletion_successes
def test_with_two_root_fields(self): deletions_successes: Dict[ str, bool] = self.users_table.delete_multiple_fields( key_value=TEST_ACCOUNT_ID, removers={ 'one': FieldRemover(field_path='rootFieldOne'), 'two': FieldRemover(field_path='rootFieldTwo') }) field_one_random_value = f"field1_{uuid4()}" field_one_update_success: bool = self.users_table.update_field( key_value=TEST_ACCOUNT_ID, field_path='rootFieldOne', value_to_set=field_one_random_value) self.assertTrue(field_one_update_success) retrieved_data: Optional[dict] = self.users_table.get_field( key_value=TEST_ACCOUNT_ID, field_path='(rootFieldOne, rootFieldTwo)') self.assertIsNotNone(retrieved_data) self.assertEqual(retrieved_data.get('rootFieldOne', None), field_one_random_value) self.assertEqual(retrieved_data.get('rootFieldTwo', None), None)
def test_grouped_remove_multiple_fields( self: unittest.TestCase, first_table: Union[DynamoDBBasicTable, DynamoDBCachingTable, ExternalDynamoDBApiBasicTable, ExternalDynamoDBApiCachingTable], second_table: Union[DynamoDBBasicTable, DynamoDBCachingTable, ExternalDynamoDBApiBasicTable, ExternalDynamoDBApiCachingTable], is_caching: bool, primary_key_name: str): def generate_update_container_fields_text_values() -> Tuple[str, str]: container_field_one_random_text_value: str = f"container_fieldOne_randomTextValue_{uuid4()}" container_field_two_random_text_value: str = f"container_fieldTwo_randomTextValue_{uuid4()}" first_table_container_fields_update_success: bool = first_table.update_multiple_fields( key_value=TEST_ACCOUNT_ID, setters=[ FieldSetter( field_path='container.nestedFieldOne', value_to_set=container_field_one_random_text_value), FieldSetter(field_path='container.nestedFieldTwo', value_to_set=container_field_two_random_text_value) ]) self.assertTrue(first_table_container_fields_update_success) if is_caching is True: self.assertTrue(first_table.commit_operations()) first_table.clear_cached_data() return container_field_one_random_text_value, container_field_two_random_text_value first_generated_container_field_one_random_text_value, first_generated_container_field_two_random_text_value = generate_update_container_fields_text_values( ) second_table_removed_container_fields_without_data_validation: Dict[ str, Optional[Any]] = second_table.grouped_remove_multiple_fields( key_value=TEST_ACCOUNT_ID, data_validation=False, removers={ 'fieldOne': FieldRemover(field_path='container.nestedFieldOne'), 'fieldTwo': FieldRemover(field_path='container.nestedFieldTwo') }) self.assertEqual( { 'fieldOne': (first_generated_container_field_one_random_text_value if is_caching is not True else { 'value': first_generated_container_field_one_random_text_value, 'fromCache': False }), 'fieldTwo': (first_generated_container_field_two_random_text_value if is_caching is not True else { 'value': first_generated_container_field_two_random_text_value, 'fromCache': False }) }, second_table_removed_container_fields_without_data_validation) if is_caching is True: second_table.clear_cached_data() second_generated_container_field_one_random_text_value, second_generated_container_field_two_random_text_value = generate_update_container_fields_text_values( ) second_table_removed_container_fields_with_data_validation: Dict[ str, Optional[int]] = second_table.grouped_remove_multiple_fields( key_value=TEST_ACCOUNT_ID, data_validation=True, removers={ 'fieldOne': FieldRemover(field_path='container.nestedFieldOne'), 'fieldTwo': FieldRemover(field_path='container.nestedFieldTwo') }) self.assertEqual( { 'fieldOne': (None if is_caching is not True else { 'value': None, 'fromCache': False }), 'fieldTwo': (None if is_caching is not True else { 'value': None, 'fromCache': False }) }, second_table_removed_container_fields_with_data_validation)