initial changes

This commit is contained in:
Guille Gutierrez 2023-07-26 15:03:31 -04:00
parent 5afb60e7c4
commit 4add8b2cff
5 changed files with 64 additions and 56 deletions

View File

@ -72,7 +72,7 @@ class DBControl:
:param city_id: City ID :param city_id: City ID
:return: CityObject :return: CityObject
""" """
return self._city_object.get_by_name_and_city(name, city_id) return self._city_object.get_by_name_or_alias_and_city(name, city_id)
def results(self, user_id, application_id, cities, result_names=None) -> Dict: def results(self, user_id, application_id, cities, result_names=None) -> Dict:
""" """
@ -93,9 +93,9 @@ class DBControl:
city_id = result_set.id city_id = result_set.id
results[city_name] = [] results[city_name] = []
for building_name in city[city_name]: for building_name in city[city_name]:
if self._city_object.get_by_name_and_city(building_name, city_id) is None: if self._city_object.get_by_name_or_alias_and_city(building_name, city_id) is None:
continue continue
city_object_id = self._city_object.get_by_name_and_city(building_name, city_id).id city_object_id = self._city_object.get_by_name_or_alias_and_city(building_name, city_id).id
_ = self._simulation_results.get_simulation_results_by_city_id_city_object_id_and_names( _ = self._simulation_results.get_simulation_results_by_city_id_city_object_id_and_names(
city_id, city_id,
city_object_id, city_object_id,
@ -107,16 +107,17 @@ class DBControl:
results[city_name].append(values) results[city_name].append(values)
return results return results
def persist_city(self, city: City, pickle_path, application_id: int, user_id: int): def persist_city(self, city: City, pickle_path, scenario, application_id: int, user_id: int):
""" """
Creates a city into the database Creates a city into the database
:param city: City to be stored :param city: City to be stored
:param pickle_path: Path to save the pickle file :param pickle_path: Path to save the pickle file
:param scenario: Simulation scenario name
:param application_id: Application id owning this city :param application_id: Application id owning this city
:param user_id: User who create the city :param user_id: User who create the city
return identity_id return identity_id
""" """
return self._city_repository.insert(city, pickle_path, application_id, user_id) return self._city_repository.insert(city, pickle_path, scenario, application_id, user_id)
def update_city(self, city_id, city): def update_city(self, city_id, city):
""" """

View File

@ -20,19 +20,17 @@ class City(Models):
id = Column(Integer, Sequence('city_id_seq'), primary_key=True) id = Column(Integer, Sequence('city_id_seq'), primary_key=True)
pickle_path = Column(String, nullable=False) pickle_path = Column(String, nullable=False)
name = Column(String, nullable=False) name = Column(String, nullable=False)
level_of_detail = Column(Integer, nullable=False) scenario = Column(String, nullable=False)
climate_file = Column(String, nullable=False)
application_id = Column(Integer, ForeignKey('application.id'), nullable=False) application_id = Column(Integer, ForeignKey('application.id'), nullable=False)
user_id = Column(Integer, ForeignKey('user.id'), nullable=True) user_id = Column(Integer, ForeignKey('user.id'), nullable=True)
hub_release = Column(String, nullable=False) hub_release = Column(String, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow) created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, pickle_path, name, level_of_detail, climate_file, application_id, user_id, hub_release): def __init__(self, pickle_path, name, scenario, application_id, user_id, hub_release):
self.pickle_path = str(pickle_path) self.pickle_path = str(pickle_path)
self.name = name self.name = name
self.level_of_detail = level_of_detail self.scenario = scenario
self.climate_file = climate_file
self.application_id = application_id self.application_id = application_id
self.user_id = user_id self.user_id = user_id
self.hub_release = hub_release self.hub_release = hub_release

View File

@ -34,11 +34,12 @@ class City(Repository):
cls._instance = super(City, cls).__new__(cls) cls._instance = super(City, cls).__new__(cls)
return cls._instance return cls._instance
def insert(self, city: CityHub, pickle_path, application_id, user_id: int): def insert(self, city: CityHub, pickle_path, scenario, application_id, user_id: int):
""" """
Inserts a city Inserts a city
:param city: The complete city instance :param city: The complete city instance
:param pickle_path: Path to the pickle :param pickle_path: Path to the pickle
:param scenario: Simulation scenario name
:param application_id: Application id owning the instance :param application_id: Application id owning the instance
:param user_id: User id owning the instance :param user_id: User id owning the instance
:return: Identity id :return: Identity id
@ -48,8 +49,7 @@ class City(Repository):
db_city = Model( db_city = Model(
pickle_path, pickle_path,
city.name, city.name,
city.level_of_detail.geometry, scenario,
'None' if city.climate_file is None else str(city.climate_file),
application_id, application_id,
user_id, user_id,
__version__) __version__)
@ -98,21 +98,19 @@ class City(Repository):
logging.error('Error while fetching city %s', err) logging.error('Error while fetching city %s', err)
raise SQLAlchemyError from err raise SQLAlchemyError from err
def get_by_user_id_application_id_and_name(self, user_id, application_id, city_name) -> Model: def get_by_user_id_application_id_and_scenario(self, user_id, application_id, scenario) -> Model:
""" """
Fetch city based on the user who created it Fetch city based on the user who created it
:param user_id: the user id :param user_id: the user id
:param application_id: the application id :param application_id: the application id
:param city_name: the city name :param scenario: simulation scenario name
:return: ModelCity :return: [ModelCity]
""" """
try: try:
result_set = self.session.execute(select(Model).where(Model.user_id == user_id, result_set = self.session.execute(select(Model).where(Model.user_id == user_id,
Model.application_id == application_id, Model.application_id == application_id,
Model.name == city_name Model.scenario == scenario
)).first() )).all()
if result_set is not None:
result_set = result_set[0]
return result_set return result_set
except SQLAlchemyError as err: except SQLAlchemyError as err:
logging.error('Error while fetching city by name %s', err) logging.error('Error while fetching city by name %s', err)

View File

@ -7,7 +7,7 @@ Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
import datetime import datetime
import logging import logging
from sqlalchemy import select from sqlalchemy import select, or_
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from hub.city_model_structure.building import Building from hub.city_model_structure.building import Building
@ -39,7 +39,7 @@ class CityObject(Repository):
:param building: the city object (only building for now) to be inserted :param building: the city object (only building for now) to be inserted
return Identity id return Identity id
""" """
city_object = self.get_by_name_and_city(building.name, city_id) city_object = self.get_by_name_or_alias_and_city(building.name, city_id)
if city_object is not None: if city_object is not None:
raise SQLAlchemyError(f'A city_object named {building.name} already exists in that city') raise SQLAlchemyError(f'A city_object named {building.name} already exists in that city')
try: try:
@ -96,7 +96,7 @@ class CityObject(Repository):
logging.error('Error while deleting application %s', err) logging.error('Error while deleting application %s', err)
raise SQLAlchemyError from err raise SQLAlchemyError from err
def get_by_name_and_city(self, name, city_id) -> Model: def get_by_name_or_alias_and_city(self, name, city_id) -> Model:
""" """
Fetch a city object based on name and city id Fetch a city object based on name and city id
:param name: city object name :param name: city object name
@ -106,7 +106,7 @@ class CityObject(Repository):
_city_object = None _city_object = None
try: try:
_city_object = self.session.execute(select(Model).where( _city_object = self.session.execute(select(Model).where(
Model.name == name, Model.city_id == city_id or_(Model.name == name, Model.aliases.contains(f'%{name}%')), Model.city_id == city_id
)).first() )).first()
return _city_object[0] return _city_object[0]
except SQLAlchemyError as err: except SQLAlchemyError as err:

View File

@ -14,6 +14,7 @@ from unittest import TestCase
from pathlib import Path from pathlib import Path
import sqlalchemy.exc import sqlalchemy.exc
from hub.helpers.data.montreal_function_to_hub_function import MontrealFunctionToHubFunction
from hub.imports.geometry_factory import GeometryFactory from hub.imports.geometry_factory import GeometryFactory
from hub.imports.construction_factory import ConstructionFactory from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory from hub.imports.usage_factory import UsageFactory
@ -52,7 +53,7 @@ class Control:
self._skip_reason = f'.env file missing at {dotenv_path}' self._skip_reason = f'.env file missing at {dotenv_path}'
return return
dotenv_path = str(dotenv_path) dotenv_path = str(dotenv_path)
repository = Repository(db_name='hub_unittests', app_env='TEST', dotenv_path=dotenv_path) repository = Repository(db_name='montreal_retrofit_test', app_env='TEST', dotenv_path=dotenv_path)
engine = create_engine(repository.configuration.connection_string) engine = create_engine(repository.configuration.connection_string)
try: try:
# delete test database if it exists # delete test database if it exists
@ -71,11 +72,15 @@ class Control:
CityObject.__table__.create(bind=repository.engine, checkfirst=True) CityObject.__table__.create(bind=repository.engine, checkfirst=True)
SimulationResults.__table__.create(bind=repository.engine, checkfirst=True) SimulationResults.__table__.create(bind=repository.engine, checkfirst=True)
city_file = "tests_data/FZK_Haus_LoD_2.gml" city_file = Path('tests_data/test.geojson').resolve()
output_path = Path('tests_outputs/').resolve() output_path = Path('tests_outputs/').resolve()
self._city = GeometryFactory('citygml', self._city = GeometryFactory('geojson',
city_file, city_file,
function_to_hub=Dictionaries().alkis_function_to_hub_function).city height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
aliases_field=['ID_UEV', 'CIVIQUE_DE', 'NOM_RUE'],
function_field='CODE_UTILI',
function_to_hub=MontrealFunctionToHubFunction().dictionary).city
ConstructionFactory('nrcan', self._city).enrich() ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich() UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city).enrich() WeatherFactory('epw', self._city).enrich()
@ -84,7 +89,6 @@ class Control:
subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL) subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL)
ResultFactory('sra', self._city, output_path).enrich() ResultFactory('sra', self._city, output_path).enrich()
for building in self._city.buildings: for building in self._city.buildings:
building.energy_systems_archetype_name = 'system 1 gas pv' building.energy_systems_archetype_name = 'system 1 gas pv'
EnergySystemsFactory('montreal_custom', self._city).enrich() EnergySystemsFactory('montreal_custom', self._city).enrich()
@ -103,6 +107,7 @@ class Control:
self._application_id = self._database.persist_application('test', 'test application', self.application_uuid) self._application_id = self._database.persist_application('test', 'test application', self.application_uuid)
self._user_id = self._database.create_user('Admin', self._application_id, 'Admin@123', UserRoles.Admin) self._user_id = self._database.create_user('Admin', self._application_id, 'Admin@123', UserRoles.Admin)
self._pickle_path = 'tests_data/pickle_path.bz2' self._pickle_path = 'tests_data/pickle_path.bz2'
print('done')
@property @property
def database(self): def database(self):
@ -167,6 +172,7 @@ TestDBFactory
city_id = control.database.persist_city( city_id = control.database.persist_city(
control.city, control.city,
control.pickle_path, control.pickle_path,
control.city.name,
control.application_id, control.application_id,
control.user_id) control.user_id)
control.database.delete_city(city_id) control.database.delete_city(city_id)
@ -222,8 +228,10 @@ TestDBFactory
yearly_cooling_consumption = building.cooling_consumption[cte.YEAR] yearly_cooling_consumption = building.cooling_consumption[cte.YEAR]
monthly_domestic_hot_water_consumption = building.domestic_hot_water_consumption[cte.MONTH] monthly_domestic_hot_water_consumption = building.domestic_hot_water_consumption[cte.MONTH]
yearly_domestic_hot_water_consumption = building._domestic_hot_water_consumption[cte.YEAR] yearly_domestic_hot_water_consumption = building._domestic_hot_water_consumption[cte.YEAR]
monthly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[cte.MONTH] monthly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[
yearly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[cte.YEAR] cte.MONTH]
yearly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[
cte.YEAR]
monthly_on_site_electrical_production = building.onsite_electrical_production[cte.MONTH] monthly_on_site_electrical_production = building.onsite_electrical_production[cte.MONTH]
yearly_on_site_electrical_production = building.onsite_electrical_production[cte.YEAR] yearly_on_site_electrical_production = building.onsite_electrical_production[cte.YEAR]
results = json.dumps({cte.INSEL_MEB: [ results = json.dumps({cte.INSEL_MEB: [
@ -260,12 +268,15 @@ TestDBFactory
results, city_object_id=db_building_id) results, city_object_id=db_building_id)
self.assertEqual(1, len(city_objects_id), 'wrong number of results') self.assertEqual(1, len(city_objects_id), 'wrong number of results')
self.assertIsNotNone(city_objects_id[0], 'city_object_id is None') self.assertIsNotNone(city_objects_id[0], 'city_object_id is None')
"""
for _id in city_objects_id: for _id in city_objects_id:
control.database.delete_results_by_name('insel meb', city_object_id=_id) control.database.delete_results_by_name('insel meb', city_object_id=_id)
control.database.delete_city(city_id) control.database.delete_city(city_id)
@classmethod @classmethod
@unittest.skipIf(control.skip_test, control.skip_reason) @unittest.skipIf(control.skip_test, control.skip_reason)
def tearDownClass(cls): def tearDownClass(cls):
control.database.delete_application(control.application_uuid) control.database.delete_application(control.application_uuid)
control.database.delete_user(control.user_id) control.database.delete_user(control.user_id)
"""