diff --git a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py index 5376cba1..b33c1a03 100644 --- a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py +++ b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py @@ -71,7 +71,7 @@ class Data(SQLSubModel): major, minor, release = version.strip().split(".") created = False - if major == "0" and int(minor) <= 1: + if major == "0" and minor == "0": if int(release) < 7: cls._db_create(execute) created = True @@ -249,7 +249,7 @@ class BoundaryConditionAdisTS(SQLSubModel): major, minor, release = version.strip().split(".") created = False - if major == "0" and int(minor) <= 1: + if major == "0" and minor == "0": if int(release) < 7: cls._db_create(execute) created = True diff --git a/src/Model/Pollutants/Pollutants.py b/src/Model/Pollutants/Pollutants.py index 53799c85..1026851f 100644 --- a/src/Model/Pollutants/Pollutants.py +++ b/src/Model/Pollutants/Pollutants.py @@ -278,8 +278,10 @@ class PollutantCharacteristics(SQLSubModel): class Pollutants(SQLSubModel): - _sub_classes = [PollutantCharacteristics, - BoundaryConditionAdisTS] + _sub_classes = [ + PollutantCharacteristics, + # BoundaryConditionAdisTS + ] def __init__(self, id: int = -1, name: str = "", status=None, owner_scenario=-1): @@ -426,10 +428,6 @@ class Pollutants(SQLSubModel): new_pollutant._data = PollutantCharacteristics._db_load( execute, data=data ) - - new_pollutant._boundary_conditions_adists = BoundaryConditionAdisTS._db_load( - execute, data=data - ) new_pollutant._boundary_conditions_adists = ( BoundaryConditionAdisTS._db_load( diff --git a/src/Model/Scenario.py b/src/Model/Scenario.py index 58d6257a..10c5a3f7 100644 --- a/src/Model/Scenario.py +++ b/src/Model/Scenario.py @@ -17,16 +17,51 @@ # -*- coding: utf-8 -*- import os +import logging from tools import logger_exception from Model.Tools.PamhyrDB import SQLSubModel +logger = logging.getLogger() + class Scenario(SQLSubModel): _id_cnt = 0 _sub_classes = [] + tables_with_deleted_column = [ + # Adists + "output_rk_adists", + "boundary_condition_adists", "boundary_condition_data_adists", + "lateral_contribution_adists", "lateral_contribution_data_adists", + "initial_conditions_adists", "initial_conditions_adists_data", + "d90_adists", "d90_adists_spec", + "dif_adists_spec", + "pollutants", "pollutants_characteristics", + # Hydraulic + "additional_files", + "boundary_condition", "boundary_condition_data", + "lateral_contribution", "lateral_contribution_data", + "friction", "stricklers", + "hydraulic_structures", + "hydraulic_structures_basic", + "initial_conditions", + "sedimentary_layer", "sedimentary_layer_layer", + "reservoir", "reservoir_data", + "rep_lines", + "geometry_pointXYZ", "geometry_profileXYZ", + "river_reach", "river_node", + "geotiff", "reservoir", "reservoir_data", + ] + + related_tables = tables_with_deleted_column + [ + "dif_adists", + "solver_parameter", + "hydraulic_structures_basic_value", + "results", "results_data", "results_add_data", + ] + def __init__(self, id: int = -1, name: str = "", @@ -171,33 +206,7 @@ class Scenario(SQLSubModel): def drop_all(self, execute): execute(f"DELETE FROM scenario WHERE id = {self.id}") - tables = [ - # Adists - "output_rk_adists", - "boundary_condition_adists", "boundary_condition_data_adists", - "lateral_contribution_adists", "lateral_contribution_data_adists", - "initial_conditions_adists", "initial_conditions_adists_data", - "d90_adists", "d90_adists_spec", - "dif_adists", "dif_adists_spec", - "pollutants", "pollutants_characteristics", - # Hydraulic - "additional_files", - "boundary_condition", "boundary_condition_data", - "lateral_contribution", "lateral_contribution_data", - "friction", "stricklers", - "hydraulic_structures", - "hydraulic_structures_basic", "hydraulic_structures_basic_value", - "initial_conditions", - "sedimentary_layer", "sedimentary_layer_layer", - "reservoir", "reservoir_data", - "rep_lines", - "solver_parameter", - "geometry_pointXYZ", "geometry_profileXYZ", - "river_reach", "river_node", - "geotiff", "reservoir", "reservoir_data", - # Results - "results", "results_data", "results_add_data", - ] + tables = self.related_tables for table in tables: execute( @@ -207,6 +216,58 @@ class Scenario(SQLSubModel): return True + def get_parent_branch(self): + def aux(scenario, acc): + if scenario is None: + return acc + + return aux(scenario.parent, [scenario.id] + acc) + + return aux(self, []) + + def drop_deleted_data(self, execute): + tables = self.tables_with_deleted_column + branch = self.get_parent_branch() + + for table in tables: + if self.parent is None: + # This scenario is the default scenario, so we can + # delete all data marked as deleted + execute( + f"DELETE FROM {table} " + + f"WHERE scenario = {self.id} " + + "AND deleted = TRUE" + ) + continue + + # Select pamhyr_id for each deleted data in this scenario + # who do not exists into parents scenarios + ids = execute( + f""" + SELECT pamhyr_id FROM {table} + WHERE deleted = TRUE + AND scenario = {self.id} + AND pamhyr_id NOT IN ( + SELECT pamhyr_id FROM {table} + WHERE scenario IN + ({', '.join(map(str, branch[:-1]))}) + ) + """, fetch_one=False + ) + if ids is None or len(ids) == 0: + continue + + logger.debug( + f"(s{self.id}) Drop deleted data into '{table}' : {ids}" + ) + + execute( + f"DELETE FROM {table} " + + f"WHERE scenario = {self.id} " + + "AND pamhyr_id IN " + + f"({', '.join(map(lambda x: str(x[0]), ids))})" + ) + @property def id(self): return self._id diff --git a/src/Model/Study.py b/src/Model/Study.py index 23113ab9..2ec031a7 100644 --- a/src/Model/Study.py +++ b/src/Model/Study.py @@ -449,6 +449,13 @@ class Study(SQLModel): [self.scenarios, self._river], data=progress ) + + # Clear DB for each scenarios + for scenar in self.scenarios.lst: + scenar.drop_deleted_data(self.execute) + + progress() + self.commit() def sql_save_request_count(self, *args, **kargs): @@ -459,7 +466,7 @@ class Study(SQLModel): [self.scenarios, self._river] ) logger.debug(cnt) - return cnt + 7 + return cnt + 8 def close(self): """Close db connection @@ -518,7 +525,8 @@ class Study(SQLModel): data["study"] = self river._db_load_results(sql_exec, data=data) - self._river_scenario_cache[scenario] = river + # FIXME: Disable scenario cache to save memory usage + # self._river_scenario_cache[scenario] = river self.status.scenario = old_scenario return river diff --git a/src/Solver/AdisTS.py b/src/Solver/AdisTS.py index a8225a64..b8310dfb 100644 --- a/src/Solver/AdisTS.py +++ b/src/Solver/AdisTS.py @@ -845,7 +845,9 @@ class AdisTSwc(AdisTS): # seventh line (useless) for k in range(0, ismax, kbl): data = np.fromfile(f, dtype=np.int32, count=1) # (start) - zero = np.fromfile(f, dtype=np.int32, count=min(k + kbl, ismax) - k) + zero = np.fromfile( + f, dtype=np.int32, count=min(k + kbl, ismax) - k + ) data = np.fromfile(f, dtype=np.int32, count=1) # (end) # end header # data