From 6c703cbb64dd95aebf26f0c2b543754aca8a099f Mon Sep 17 00:00:00 2001 From: r_sanchez Date: Wed, 22 Nov 2023 12:09:28 -0500 Subject: [PATCH] took changes from hub --- cerc_persistence/db_setup.py | 8 ++--- cerc_persistence/models/city.py | 2 +- cerc_persistence/models/city_object.py | 3 +- cerc_persistence/repositories/city_object.py | 34 ++++++++++++++++++- .../repositories/simulation_results.py | 30 ++++++++++++++-- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/cerc_persistence/db_setup.py b/cerc_persistence/db_setup.py index 495f3ee..3b76fe1 100644 --- a/cerc_persistence/db_setup.py +++ b/cerc_persistence/db_setup.py @@ -50,14 +50,14 @@ class DBSetup: name = 'AdminTool' description = 'Admin tool to control city persistence and to test the API v1.4' logging.info('Creating default admin tool application...') - application_id = application_repo.insert(name, description, application_uuid) + application = application_repo.insert(name, description, application_uuid) - if isinstance(application_id, dict): - logging.info(application_id) + if isinstance(application, dict): + logging.info(application) else: msg = f'Created Admin tool with application_uuid: {application_uuid}' logging.info(msg) - return application_id + return application.id @staticmethod def _create_admin_user(user_repo, admin_password, application_id): diff --git a/cerc_persistence/models/city.py b/cerc_persistence/models/city.py index cb138ac..6c468b9 100644 --- a/cerc_persistence/models/city.py +++ b/cerc_persistence/models/city.py @@ -33,4 +33,4 @@ class City(Models): self.scenario = scenario self.application_id = application_id self.user_id = user_id - self.hub_release = hub_release + self.hub_release = hub_release \ No newline at end of file diff --git a/cerc_persistence/models/city_object.py b/cerc_persistence/models/city_object.py index d245c93..0b602a3 100644 --- a/cerc_persistence/models/city_object.py +++ b/cerc_persistence/models/city_object.py @@ -50,8 +50,7 @@ class CityObject(Models): self.volume = building.volume self.area = building.floor_area self.roof_area = sum(roof.solid_polygon.area for roof in building.roofs) - self.total_pv_area = sum( - roof.solid_polygon.area * roof.solar_collectors_area_reduction_factor for roof in building.roofs) + self.total_pv_area = sum(roof.solid_polygon.area * roof.solar_collectors_area_reduction_factor for roof in building.roofs) storeys = building.storeys_above_ground wall_area = 0 window_ratio = 0 diff --git a/cerc_persistence/repositories/city_object.py b/cerc_persistence/repositories/city_object.py index afc7542..c464280 100644 --- a/cerc_persistence/repositories/city_object.py +++ b/cerc_persistence/repositories/city_object.py @@ -90,7 +90,7 @@ class CityObject(Repository): session.query(Model).filter(Model.city_id == city_id, Model.name == name).delete() session.commit() except SQLAlchemyError as err: - logging.error('Error while deleting city_object %s', err) + logging.error('Error while deleting application %s', err) raise SQLAlchemyError from err def get_by_name_or_alias_and_city(self, name, city_id) -> Model: @@ -124,3 +124,35 @@ class CityObject(Repository): except IndexError as err: logging.error('Error while fetching city object by name and city, empty result %s', err) raise IndexError from err + + def get_by_name_or_alias_in_cities(self, name, city_ids) -> Model: + """ + Fetch a city object based on name and city ids + :param name: city object name + :param city_ids: a list of city identifiers + :return: [CityObject] with the provided name or alias belonging to the city with id city_id + """ + try: + # search by name first + with Session(self.engine) as session: + city_object = session.execute(select(Model).where(Model.name == name, Model.city_id.in_(tuple(city_ids)))).first() + if city_object is not None: + return city_object[0] + # name not found, so search by alias instead + city_objects = session.execute( + select(Model).where(Model.aliases.contains(name), Model.city_id.in_(tuple(city_ids))) + ).all() + for city_object in city_objects: + aliases = city_object[0].aliases.replace('{', '').replace('}', '').split(',') + for alias in aliases: + if alias == name: + # force the name as the alias + city_object[0].name = name + return city_object[0] + return None + except SQLAlchemyError as err: + logging.error('Error while fetching city object by name and city: %s', err) + raise SQLAlchemyError from err + except IndexError as err: + logging.error('Error while fetching city object by name and city, empty result %s', err) + raise IndexError from err diff --git a/cerc_persistence/repositories/simulation_results.py b/cerc_persistence/repositories/simulation_results.py index f8f0efd..5d7ef08 100644 --- a/cerc_persistence/repositories/simulation_results.py +++ b/cerc_persistence/repositories/simulation_results.py @@ -84,7 +84,7 @@ class SimulationResults(Repository): else: raise NotImplementedError('Missing either city_id or city_object_id') except SQLAlchemyError as err: - logging.error('Error while updating simulation results %s', err) + logging.error('Error while updating city object %s', err) raise SQLAlchemyError from err def delete(self, name: str, city_id=None, city_object_id=None): @@ -135,8 +135,8 @@ class SimulationResults(Repository): logging.error('Error while fetching city by city_id: %s', err) raise SQLAlchemyError from err - def get_simulation_results_by_city_id_city_object_id_and_names(self, city_id, city_object_id, - result_names=None) -> [Model]: + def get_simulation_results_by_city_id_city_object_id_and_names(self, city_id, city_object_id, result_names=None) -> [ + Model]: """ Fetch the simulation results based in the city_id or city_object_id with the given names or all :param city_id: the city id @@ -161,3 +161,27 @@ class SimulationResults(Repository): except SQLAlchemyError as err: logging.error('Error while fetching city by city_id: %s', err) raise SQLAlchemyError from err + + def get_simulation_results_by_city_object_id_and_names(self, city_object_id, result_names=None) -> [Model]: + """ + Fetch the simulation results based in the city_object_id with the given names or all + :param city_object_id: the city object id + :param result_names: if given filter the results + :return: [SimulationResult] + """ + try: + with Session(self.engine) as session: + result_set = session.execute(select(Model).where( + Model.city_object_id == city_object_id + )) + results = [r[0] for r in result_set] + if not result_names: + return results + filtered_results = [] + for result in results: + if result.name in result_names: + filtered_results.append(result) + return filtered_results + except SQLAlchemyError as err: + logging.error('Error while fetching city by city_id: %s', err) + raise SQLAlchemyError from err