def add_and_remove_parameter_dimension_v2(parameters, source_relationship_class, link_relationship_class, target_relationship_class):
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links the new dimension to one of the old dimensions
    target_objects = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target, source = relationship_row.object_name_list.split(",")
        target_objects[source] = target

    # Entities
    objects_to_move = _extract_relationship_objects(source_relationship_class)

    # Update the dimensions of the entities and add to a list 
    modified_relationships = []
    for object1, object2, object3, object4 in objects_to_move:
        object_add = target_objects[object1]
        modified_relationships.append((target_relationship_class, (object_add, object1, object2, object3)))
        
    import_relationships(out_db, modified_relationships)

    # Parameter values
    values_to_move = _extract_relationship_parameter_values(parameters, source_relationship_class)

    # Add the previous parameter values to a list with the updated relationship dimensions
    moved_values = []
    for (object1, object2, object3, new_parameter), _, x, alternative in values_to_move:
        object_add = target_objects[object1]
        moved_values.append((target_relationship_class, (object_add, object1, object2, object3), new_parameter, x, alternative))

    import_relationship_parameter_values(out_db, moved_values)
def remove_parameter_dimension(parameters, source_relationship_class, target_relationship_class, minmax):
    # Entities
    objects_to_move = _extract_relationship_objects(source_relationship_class)

    # Reduce the dimensions of the entities and add to a list  
    modified_relationships = []
    for object1, object2, object3 in objects_to_move:
        modified_relationships.append((target_relationship_class, (object1, object2)))
        
    import_relationships(out_db, modified_relationships)

    # Parameter values
    parameter_values = export_relationship_parameter_values(in_db)

    # Add the parameter values from the source class to a dict
    modified_values = {}
    for value in parameter_values:
        if value[P.CLASS] == source_relationship_class and value[P.NAME] in parameters:
            object1, object2, object3 = value[P.OBJECT]
            modified_values.setdefault((object1, object2, parameters[value[P.NAME]], value[P.ALTERNATIVE]), []).append(value[P.X])

    # Add the previous parameter values to a list with the reduced relationship dimensions
    moved_values = []
    min_or_max = min if minmax == "min" else max
    for object1, object2, new_parameter, alternative in modified_values:
        x = min_or_max(modified_values[(object1, object2, new_parameter, alternative)])
        moved_values.append((target_relationship_class, (object1, object2), new_parameter, x, alternative))

    import_relationship_parameter_values(out_db, moved_values)
def add_parameter_dimension_2links_v2(parameters, source_object_class, link_relationship_class, link_relationship_class2, target_relationship_class):
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links a temporary dimension to the old dimension
    target_temp = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target1, source, target2 = relationship_row.object_name_list.split(",") #node, unit, io
        if source not in target_temp:
            target_temp[source] = list()
        target_temp[source].extend([(target1, target2)]) #target_temp[unit] = [..., (node, io)]
        
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class2).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links the new dimension to the old dimension
    target_temp2 = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target, source = relationship_row.object_name_list.split(",") #commodity, node
        target_temp2[source] = target #target_temp2[node] = commodity
        
    target_final = {}
    for source in target_temp:
        if source not in target_final:
            target_final[source] = list()           
        list_of_items = target_temp[source]
     
        for target1, target2 in list_of_items:
            target3 = target_temp2[target1]
            target_final[source].extend([(target3, target1, target2)]) #target_final[unit] = [..., (commodity, node, io)]

    # Entities
    objects = _extract_objects(source_object_class)

    # Extend the dimensions of the entities and add to a list
    new_relationships = []
    for object1 in objects:
        relationships_add = target_final[object1]
        for object2, object3, object4 in relationships_add:
            new_relationships.append((target_relationship_class, (object2, object3, object1, object4)))

    import_relationships(out_db, new_relationships)

    # Parameter values
    values_to_move = _extract_object_parameter_values(parameters, source_object_class)

    # Add the previous parameter values to a list with the extended relationship dimensions 
    moved_values = []
    for object1, new_parameter, x, alternative in values_to_move:
        relationships_add = target_final[object1]
        for object2, object3, object4 in relationships_add:
            moved_values.append((target_relationship_class, (object2, object3, object1, object4), new_parameter, x, alternative))

    import_relationship_parameter_values(out_db, moved_values)
def add_parameter_dimension_2links(parameters, source_object_class, link_relationship_class, link_relationship_class2, target_relationship_class):
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links a temporary dimension to the old dimension
    target_objects_temp = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target, source = relationship_row.object_name_list.split(",") #flow, unit
        target_objects_temp[source] = target #target_objects_temp[unit] = flow
        
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class2).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links the new dimension to the old dimension
    target_objects = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target, source, dummy = relationship_row.object_name_list.split(",") #node, unit
        if source in target_objects_temp:
            target_objects[target_objects_temp[source]] = target #target_objects[flow] = node

    # Entities
    objects_to_move = _extract_objects(source_object_class)

    # Extend the dimensions of the entities and add to a list 
    modified_relationships = []
    for object1 in objects_to_move:
        object_add = target_objects[object1]
        modified_relationships.append((target_relationship_class, (object1, object_add)))

    import_relationships(out_db, modified_relationships)

    # Parameter values
    values_to_move = _extract_object_parameter_values(parameters, source_object_class)

    # Add the previous parameter values to a list with the extended relationship dimensions 
    moved_values = []
    for object1, new_parameter, x, alternative in values_to_move:
        object_add = target_objects[object1]
        moved_values.append((target_relationship_class, (object1, object_add), new_parameter, x, alternative))

    import_relationship_parameter_values(out_db, moved_values)
def add_and_remove_parameter_dimension(parameters, source_relationship_class, link_relationship_class, target_relationship_class, minmax):
    subquery = in_db.wide_relationship_class_sq
    class_row = in_db.query(subquery).filter(subquery.c.name == link_relationship_class).first()
    subquery = in_db.wide_relationship_sq

    # Create a dictionary that links the new dimension to one of the old dimensions
    target_objects = {}
    for relationship_row in in_db.query(subquery).filter(subquery.c.class_id == class_row.id):
        target, source = relationship_row.object_name_list.split(",")
        target_objects[source] = target

    # Entities
    objects_to_move = _extract_relationship_objects(source_relationship_class)

    # Update the dimensions of the entities and add to a list 
    modified_relationships = []
    for object1, object2, object3, object4 in objects_to_move:
        object_add = target_objects[object1]
        modified_relationships.append((target_relationship_class, (object_add, object1, object2, object3)))

    import_relationships(out_db, modified_relationships)

    # Parameter values
    parameter_values = export_relationship_parameter_values(in_db)

    # Add the parameter values from the source class to a dict
    values_to_modify = {}
    for value in parameter_values:
        if value[P.CLASS] == source_relationship_class and value[P.NAME] in parameters:
            object1, object2, object3, object4 = value[P.OBJECT]
            values_to_modify.setdefault((object1, object2, object3, parameters[value[P.NAME]], value[P.ALTERNATIVE]), []).append(value[P.X])

    # Add the previous parameter values to a list with the updated relationship dimensions
    moved_values = []
    min_or_max = min if minmax == "min" else max
    for object1, object2, object3, new_parameter, alternative in values_to_modify:
        object_add = target_objects[object1]
        x = min_or_max(values_to_modify[(object1, object2, object3, new_parameter, alternative)])
        moved_values.append((target_relationship_class, (object_add, object1, object2, object3), new_parameter, x, alternative))

    import_relationship_parameter_values(out_db, moved_values)
 def setUp(self):
     """Overridden method. Runs before each test."""
     app_settings = mock.MagicMock()
     logger = mock.MagicMock()
     with mock.patch("spinetoolbox.spine_db_manager.SpineDBManager.thread",
                     new_callable=mock.PropertyMock) as mock_thread:
         mock_thread.return_value = QApplication.instance().thread()
         self._db_mngr = SpineDBManager(app_settings, None)
         fetcher = self._db_mngr.get_fetcher()
     self._db_map = self._db_mngr.get_db_map("sqlite://",
                                             logger,
                                             codename="mock_db",
                                             create=True)
     import_object_classes(self._db_map, ("dog", "fish"))
     import_object_parameters(self._db_map, (("dog", "breed"), ))
     import_objects(self._db_map, (("dog", "pluto"), ("fish", "nemo")))
     import_relationship_classes(self._db_map,
                                 (("dog__fish", ("dog", "fish")), ))
     import_relationship_parameters(self._db_map,
                                    (("dog__fish", "relative_speed"), ))
     import_relationships(self._db_map, (("dog_fish", ("pluto", "nemo")), ))
     self._db_map.commit_session("Add test data")
     fetcher.fetch([self._db_map])
     self.object_table_header = [
         "object_class_name",
         "object_name",
         "parameter_name",
         "alternative_id",
         "value",
         "database",
     ]
     self.relationship_table_header = [
         "relationship_class_name",
         "object_name_list",
         "parameter_name",
         "alternative_id",
         "value",
         "database",
     ]