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
: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:
"""
@ -93,9 +93,9 @@ class DBControl:
city_id = result_set.id
results[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
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(
city_id,
city_object_id,
@ -107,16 +107,17 @@ class DBControl:
results[city_name].append(values)
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
:param city: City to be stored
:param pickle_path: Path to save the pickle file
:param scenario: Simulation scenario name
:param application_id: Application id owning this city
:param user_id: User who create the city
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):
"""

View File

@ -20,19 +20,17 @@ class City(Models):
id = Column(Integer, Sequence('city_id_seq'), primary_key=True)
pickle_path = Column(String, nullable=False)
name = Column(String, nullable=False)
level_of_detail = Column(Integer, nullable=False)
climate_file = Column(String, nullable=False)
scenario = Column(String, nullable=False)
application_id = Column(Integer, ForeignKey('application.id'), nullable=False)
user_id = Column(Integer, ForeignKey('user.id'), nullable=True)
hub_release = Column(String, nullable=False)
created = 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.name = name
self.level_of_detail = level_of_detail
self.climate_file = climate_file
self.scenario = scenario
self.application_id = application_id
self.user_id = user_id
self.hub_release = hub_release

View File

@ -34,11 +34,12 @@ class City(Repository):
cls._instance = super(City, cls).__new__(cls)
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
:param city: The complete city instance
:param pickle_path: Path to the pickle
:param scenario: Simulation scenario name
:param application_id: Application id owning the instance
:param user_id: User id owning the instance
:return: Identity id
@ -48,8 +49,7 @@ class City(Repository):
db_city = Model(
pickle_path,
city.name,
city.level_of_detail.geometry,
'None' if city.climate_file is None else str(city.climate_file),
scenario,
application_id,
user_id,
__version__)
@ -98,21 +98,19 @@ class City(Repository):
logging.error('Error while fetching city %s', 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
:param user_id: the user id
:param application_id: the application id
:param city_name: the city name
:return: ModelCity
:param scenario: simulation scenario name
:return: [ModelCity]
"""
try:
result_set = self.session.execute(select(Model).where(Model.user_id == user_id,
Model.application_id == application_id,
Model.name == city_name
)).first()
if result_set is not None:
result_set = result_set[0]
Model.scenario == scenario
)).all()
return result_set
except SQLAlchemyError as 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 logging
from sqlalchemy import select
from sqlalchemy import select, or_
from sqlalchemy.exc import SQLAlchemyError
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
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:
raise SQLAlchemyError(f'A city_object named {building.name} already exists in that city')
try:
@ -96,7 +96,7 @@ class CityObject(Repository):
logging.error('Error while deleting application %s', 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
:param name: city object name
@ -106,7 +106,7 @@ class CityObject(Repository):
_city_object = None
try:
_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()
return _city_object[0]
except SQLAlchemyError as err:

View File

@ -14,6 +14,7 @@ from unittest import TestCase
from pathlib import Path
import sqlalchemy.exc
from hub.helpers.data.montreal_function_to_hub_function import MontrealFunctionToHubFunction
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory
@ -52,7 +53,7 @@ class Control:
self._skip_reason = f'.env file missing at {dotenv_path}'
return
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)
try:
# delete test database if it exists
@ -71,11 +72,15 @@ class Control:
CityObject.__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()
self._city = GeometryFactory('citygml',
self._city = GeometryFactory('geojson',
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()
UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city).enrich()
@ -84,7 +89,6 @@ class Control:
subprocess.run([self.sra, sra_file], stdout=subprocess.DEVNULL)
ResultFactory('sra', self._city, output_path).enrich()
for building in self._city.buildings:
building.energy_systems_archetype_name = 'system 1 gas pv'
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._user_id = self._database.create_user('Admin', self._application_id, 'Admin@123', UserRoles.Admin)
self._pickle_path = 'tests_data/pickle_path.bz2'
print('done')
@property
def database(self):
@ -167,6 +172,7 @@ TestDBFactory
city_id = control.database.persist_city(
control.city,
control.pickle_path,
control.city.name,
control.application_id,
control.user_id)
control.database.delete_city(city_id)
@ -222,36 +228,38 @@ TestDBFactory
yearly_cooling_consumption = building.cooling_consumption[cte.YEAR]
monthly_domestic_hot_water_consumption = building.domestic_hot_water_consumption[cte.MONTH]
yearly_domestic_hot_water_consumption = building._domestic_hot_water_consumption[cte.YEAR]
monthly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[cte.MONTH]
yearly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[cte.YEAR]
monthly_distribution_systems_electrical_consumption = building.distribution_systems_electrical_consumption[
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]
yearly_on_site_electrical_production = building.onsite_electrical_production[cte.YEAR]
results = json.dumps({cte.INSEL_MEB: [
{'monthly_cooling_peak_load': monthly_cooling_peak_load},
{'yearly_cooling_peak_load': yearly_cooling_peak_load},
{'monthly_heating_peak_load': monthly_heating_peak_load},
{'yearly_heating_peak_load': yearly_heating_peak_load},
{'monthly_cooling_demand': monthly_cooling_demand.tolist()},
{'yearly_cooling_demand': yearly_cooling_demand.tolist()},
{'monthly_heating_demand': monthly_heating_demand.tolist()},
{'yearly_heating_demand': yearly_heating_demand.tolist()},
{'monthly_lighting_electrical_demand': monthly_lighting_electrical_demand.tolist()},
{'yearly_lighting_electrical_demand': yearly_lighting_electrical_demand.tolist()},
{'monthly_appliances_electrical_demand': monthly_appliances_electrical_demand.tolist()},
{'yearly_appliances_electrical_demand': yearly_appliances_electrical_demand.tolist()},
{'monthly_domestic_hot_water_heat_demand': monthly_domestic_hot_water_heat_demand.tolist()},
{'yearly_domestic_hot_water_heat_demand': yearly_domestic_hot_water_heat_demand.tolist()},
{'monthly_heating_consumption': monthly_heating_consumption},
{'yearly_heating_consumption': yearly_heating_consumption},
{'monthly_cooling_consumption': monthly_cooling_consumption},
{'yearly_cooling_consumption': yearly_cooling_consumption},
{'monthly_domestic_hot_water_consumption': monthly_domestic_hot_water_consumption},
{'yearly_domestic_hot_water_consumption': yearly_domestic_hot_water_consumption},
{'monthly_distribution_systems_electrical_consumption': monthly_distribution_systems_electrical_consumption},
{'yearly_distribution_systems_electrical_consumption': yearly_distribution_systems_electrical_consumption},
{'monthly_on_site_electrical_production': monthly_on_site_electrical_production},
{'yearly_on_site_electrical_production': yearly_on_site_electrical_production}
]})
{'monthly_cooling_peak_load': monthly_cooling_peak_load},
{'yearly_cooling_peak_load': yearly_cooling_peak_load},
{'monthly_heating_peak_load': monthly_heating_peak_load},
{'yearly_heating_peak_load': yearly_heating_peak_load},
{'monthly_cooling_demand': monthly_cooling_demand.tolist()},
{'yearly_cooling_demand': yearly_cooling_demand.tolist()},
{'monthly_heating_demand': monthly_heating_demand.tolist()},
{'yearly_heating_demand': yearly_heating_demand.tolist()},
{'monthly_lighting_electrical_demand': monthly_lighting_electrical_demand.tolist()},
{'yearly_lighting_electrical_demand': yearly_lighting_electrical_demand.tolist()},
{'monthly_appliances_electrical_demand': monthly_appliances_electrical_demand.tolist()},
{'yearly_appliances_electrical_demand': yearly_appliances_electrical_demand.tolist()},
{'monthly_domestic_hot_water_heat_demand': monthly_domestic_hot_water_heat_demand.tolist()},
{'yearly_domestic_hot_water_heat_demand': yearly_domestic_hot_water_heat_demand.tolist()},
{'monthly_heating_consumption': monthly_heating_consumption},
{'yearly_heating_consumption': yearly_heating_consumption},
{'monthly_cooling_consumption': monthly_cooling_consumption},
{'yearly_cooling_consumption': yearly_cooling_consumption},
{'monthly_domestic_hot_water_consumption': monthly_domestic_hot_water_consumption},
{'yearly_domestic_hot_water_consumption': yearly_domestic_hot_water_consumption},
{'monthly_distribution_systems_electrical_consumption': monthly_distribution_systems_electrical_consumption},
{'yearly_distribution_systems_electrical_consumption': yearly_distribution_systems_electrical_consumption},
{'monthly_on_site_electrical_production': monthly_on_site_electrical_production},
{'yearly_on_site_electrical_production': yearly_on_site_electrical_production}
]})
db_building_id = _building.id
city_objects_id.append(db_building_id)
@ -260,12 +268,15 @@ TestDBFactory
results, city_object_id=db_building_id)
self.assertEqual(1, len(city_objects_id), 'wrong number of results')
self.assertIsNotNone(city_objects_id[0], 'city_object_id is None')
"""
for _id in city_objects_id:
control.database.delete_results_by_name('insel meb', city_object_id=_id)
control.database.delete_city(city_id)
@classmethod
@unittest.skipIf(control.skip_test, control.skip_reason)
def tearDownClass(cls):
control.database.delete_application(control.application_uuid)
control.database.delete_user(control.user_id)
"""