Persistence refactory
This commit is contained in:
parent
5978757348
commit
672b9874f2
|
@ -1,6 +1,5 @@
|
|||
from .base_repo import BaseRepo
|
||||
from .repositories.city_repo import CityRepo
|
||||
from .repositories.heat_pump_simulation_repo import HeatPumpSimulationRepo
|
||||
from .repository import Repository
|
||||
from .repositories.city import City
|
||||
from .db_setup import DBSetup
|
||||
from .repositories.user_repo import UserRepo
|
||||
from .repositories.user import User
|
||||
from .models.user import UserRoles
|
||||
|
|
|
@ -13,10 +13,10 @@ from hub.hub_logger import logger
|
|||
Base = declarative_base()
|
||||
|
||||
|
||||
class BaseConfiguration(object):
|
||||
class Configuration:
|
||||
"""
|
||||
Configuration class to hold common persistence configuration
|
||||
"""
|
||||
Base configuration class to hold common persistence configuration
|
||||
"""
|
||||
|
||||
def __init__(self, db_name: str, dotenv_path: str, app_env='TEST'):
|
||||
"""
|
|
@ -1,13 +1,19 @@
|
|||
"""
|
||||
Database setup
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from hub.persistence import BaseRepo
|
||||
from hub.persistence import Repository
|
||||
from hub.persistence.models import Application
|
||||
from hub.persistence.models import City
|
||||
from hub.persistence.models import HeatPumpSimulation
|
||||
from hub.persistence.models import CityObject
|
||||
from hub.persistence.models import User
|
||||
from hub.persistence.models import UserRoles
|
||||
from hub.persistence.models import Application
|
||||
from hub.persistence.models import UserApplications
|
||||
from hub.persistence.repositories import UserRepo
|
||||
from hub.persistence.repositories import ApplicationRepo
|
||||
from hub.persistence.models import SimulationResults
|
||||
from hub.persistence.repositories import User as UserRepository
|
||||
from hub.persistence.repositories import Application as ApplicationRepository
|
||||
from hub.hub_logger import logger
|
||||
|
||||
|
||||
|
@ -20,14 +26,17 @@ class DBSetup:
|
|||
:param app_env:
|
||||
:param dotenv_path:
|
||||
"""
|
||||
repo = BaseRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
User.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
City.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
Application.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
UserApplications.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
HeatPumpSimulation.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._application_repo = ApplicationRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
repository = Repository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
|
||||
# Create the tables using the models
|
||||
Application.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
City.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
CityObject.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
SimulationResults.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
User.__table__.create(bind=repository.engine, checkfirst=True)
|
||||
|
||||
self._user_repo = UserRepository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._application_repo = ApplicationRepository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
|
||||
self._create_admin_user(self._user_repo, admin_password)
|
||||
self._create_admin_app(self._application_repo, application_uuid)
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
from .city import City
|
||||
from .heat_pump_simulation import HeatPumpSimulation
|
||||
from .heat_pump_simulation import SimulationTypes
|
||||
from .heat_pump_simulation import HeatPumpTypes
|
||||
from .user import User, UserRoles
|
||||
from .user_applications import UserApplications
|
||||
from .application import Application
|
||||
from .city import City
|
||||
from .city_object import CityObject
|
||||
from .simulation_results import SimulationResults
|
||||
from .user import User, UserRoles
|
||||
|
|
|
@ -11,14 +11,12 @@ from sqlalchemy.dialects.postgresql import UUID
|
|||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy import DateTime
|
||||
|
||||
from hub.persistence.db_config import Base
|
||||
|
||||
|
||||
class Application(Base):
|
||||
class Application:
|
||||
"""
|
||||
A model representation of an application
|
||||
"""
|
||||
__tablename__ = "application"
|
||||
__table__ = "application"
|
||||
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
description = Column(String, nullable=False)
|
||||
|
|
|
@ -10,13 +10,11 @@ import datetime
|
|||
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
|
||||
from sqlalchemy import DateTime, PickleType
|
||||
|
||||
from hub.persistence.db_config import Base
|
||||
|
||||
|
||||
class City(Base):
|
||||
class City:
|
||||
"""A model representation of a city
|
||||
"""
|
||||
__tablename__ = "city"
|
||||
__table__ = "city"
|
||||
id = Column(Integer, Sequence('city_id_seq'), primary_key=True)
|
||||
city = Column(PickleType, nullable=False)
|
||||
name = Column(String, nullable=False)
|
||||
|
|
|
@ -10,14 +10,11 @@ import datetime
|
|||
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
|
||||
from sqlalchemy import DateTime
|
||||
|
||||
from hub.persistence.db_config import Base
|
||||
|
||||
|
||||
class CityObject(Base):
|
||||
class CityObject:
|
||||
"""
|
||||
A model representation of an application
|
||||
"""
|
||||
__tablename__ = "city_object"
|
||||
__table__ = "city_object"
|
||||
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
|
||||
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
|
||||
name = Column(String, nullable=False)
|
||||
|
@ -41,4 +38,3 @@ class CityObject(Base):
|
|||
self.usage = usage
|
||||
self.volume = volume
|
||||
self.area = area
|
||||
|
||||
|
|
|
@ -7,18 +7,15 @@ Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
|
|||
|
||||
import datetime
|
||||
|
||||
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
|
||||
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
|
||||
from sqlalchemy import DateTime
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
from hub.persistence.db_config import Base
|
||||
|
||||
|
||||
class CityObject(Base):
|
||||
class SimulationResults:
|
||||
"""
|
||||
A model representation of an application
|
||||
"""
|
||||
__tablename__ = "simulation_results"
|
||||
__table__ = "simulation_results"
|
||||
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
|
||||
city_id = Column(Integer, ForeignKey('city.id'), nullable=True)
|
||||
city_object_id = Column(Integer, ForeignKey('city_object.id'), nullable=True)
|
||||
|
|
|
@ -5,14 +5,11 @@ Copyright © 2022 Concordia CERC group
|
|||
Project Coder Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import enum
|
||||
|
||||
from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy import DateTime, Enum
|
||||
from hub.persistence.db_config import Base
|
||||
import datetime
|
||||
from sqlalchemy.orm import validates
|
||||
import re
|
||||
import enum
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
||||
class UserRoles(enum.Enum):
|
||||
|
@ -20,10 +17,11 @@ class UserRoles(enum.Enum):
|
|||
Hub_Reader = 'Hub_Reader'
|
||||
|
||||
|
||||
class User(Base):
|
||||
"""A model representation of a city
|
||||
class User:
|
||||
"""
|
||||
__tablename__ = "user"
|
||||
A model representation of a city
|
||||
"""
|
||||
__table__ = "user"
|
||||
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
password = Column(String, nullable=False)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from .user_repo import UserRepo
|
||||
from .application_repo import ApplicationRepo
|
||||
from .user import User
|
||||
from .application import Application
|
||||
|
|
|
@ -12,11 +12,11 @@ from sqlalchemy import select
|
|||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from hub.hub_logger import logger
|
||||
from hub.persistence import BaseRepo
|
||||
from hub.persistence.models import Application
|
||||
from hub.persistence import Repository
|
||||
from hub.persistence.models import Application as Model
|
||||
|
||||
|
||||
class ApplicationRepo(BaseRepo):
|
||||
class Application(Repository):
|
||||
_instance = None
|
||||
|
||||
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
|
||||
|
@ -27,14 +27,14 @@ class ApplicationRepo(BaseRepo):
|
|||
Implemented for a singleton pattern
|
||||
"""
|
||||
if cls._instance is None:
|
||||
cls._instance = super(ApplicationRepo, cls).__new__(cls)
|
||||
cls._instance = super(Application, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def insert(self, name: str, description: str, application_uuid: str) -> Union[Application, Dict]:
|
||||
def insert(self, name: str, description: str, application_uuid: str) -> Union[Model, Dict]:
|
||||
application = self.get_by_uuid(application_uuid)
|
||||
if application is None:
|
||||
try:
|
||||
application = Application(name=name, description=description, application_uuid=application_uuid)
|
||||
application = Model(name=name, description=description, application_uuid=application_uuid)
|
||||
self.session.add(application)
|
||||
self.session.flush()
|
||||
self.session.commit()
|
||||
|
@ -53,21 +53,24 @@ class ApplicationRepo(BaseRepo):
|
|||
:return:
|
||||
"""
|
||||
try:
|
||||
self.session.query(Application).filter(Application.application_uuid == application_uuid) \
|
||||
.update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()})
|
||||
self.session.query(Model).filter(
|
||||
Model.application_uuid == application_uuid
|
||||
).update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()})
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while updating application: {err}')
|
||||
return {'err_msg': 'Error occurred while updating application'}
|
||||
|
||||
def get_by_uuid(self, application_uuid: str) -> [Application]:
|
||||
def get_by_uuid(self, application_uuid: str) -> [Model]:
|
||||
"""
|
||||
Fetch Application based on the application uuid
|
||||
:param application_uuid: the application uuid
|
||||
:return: [Application] with the provided application_uuid
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(Application).where(Application.application_uuid == application_uuid)).first()
|
||||
return self.session.execute(select(Model).where(
|
||||
Model.application_uuid == application_uuid)
|
||||
).first()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching application by application_uuid: {err}')
|
||||
|
||||
|
@ -78,7 +81,7 @@ class ApplicationRepo(BaseRepo):
|
|||
:return: None
|
||||
"""
|
||||
try:
|
||||
self.session.query(Application).filter(Application.application_uuid == application_uuid).delete()
|
||||
self.session.query(Model).filter(Model.application_uuid == application_uuid).delete()
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while deleting application: {err}')
|
|
@ -12,14 +12,14 @@ from typing import Union, Dict
|
|||
from sqlalchemy import select
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from hub.city_model_structure.city import City
|
||||
from hub.city_model_structure.city import City as CityHub
|
||||
from hub.hub_logger import logger
|
||||
from hub.persistence import BaseRepo
|
||||
from hub.persistence.models import City as DBCity
|
||||
from hub.persistence import Repository
|
||||
from hub.persistence.models import City as Model
|
||||
from hub.version import __version__
|
||||
|
||||
|
||||
class CityRepo(BaseRepo):
|
||||
class City(Repository):
|
||||
_instance = None
|
||||
|
||||
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
|
||||
|
@ -30,10 +30,10 @@ class CityRepo(BaseRepo):
|
|||
Implemented for a singleton pattern
|
||||
"""
|
||||
if cls._instance is None:
|
||||
cls._instance = super(CityRepo, cls).__new__(cls)
|
||||
cls._instance = super(City, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def insert(self, city: City, application_id, user_id: int) -> Union[City, Dict]:
|
||||
def insert(self, city: CityHub, application_id, user_id: int) -> Union[Model, Dict]:
|
||||
"""
|
||||
Insert a city
|
||||
:param city: The complete city instance
|
||||
|
@ -42,9 +42,14 @@ class CityRepo(BaseRepo):
|
|||
:return: City and Dictionary
|
||||
"""
|
||||
try:
|
||||
release = __version__
|
||||
db_city = DBCity(pickle.dumps(city), city.name, city.level_of_detail, city.climate_file, application_id, user_id,
|
||||
release)
|
||||
db_city = Model(
|
||||
pickle.dumps(city),
|
||||
city.name,
|
||||
city.level_of_detail,
|
||||
city.climate_file,
|
||||
application_id,
|
||||
user_id,
|
||||
__version__)
|
||||
|
||||
self.session.add(db_city)
|
||||
self.session.flush()
|
||||
|
@ -53,18 +58,18 @@ class CityRepo(BaseRepo):
|
|||
except SQLAlchemyError as err:
|
||||
logger.error(f'An error occurred while creating city: {err}')
|
||||
|
||||
def get_by_id(self, city_id: int) -> DBCity:
|
||||
def get_by_id(self, city_id: int) -> Model:
|
||||
"""
|
||||
Fetch a City based on the id
|
||||
:param city_id: the city id
|
||||
:return: a city
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(DBCity).where(DBCity.id == city_id)).first()[0]
|
||||
return self.session.execute(select(Model).where(Model.id == city_id)).first()[0]
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city: {err}')
|
||||
|
||||
def _get_by_hub_version(self, hub_release: str, city_name: str) -> City:
|
||||
def _get_by_hub_version_and_name(self, hub_release: str, city_name: str) -> Model:
|
||||
"""
|
||||
Fetch a City based on the name and hub project
|
||||
:param hub_release: the hub release
|
||||
|
@ -72,55 +77,50 @@ class CityRepo(BaseRepo):
|
|||
:return: a city
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(DBCity)
|
||||
.where(DBCity.hub_release == hub_release, DBCity.name == city_name)).first()
|
||||
return self.session.execute(select(Model)
|
||||
.where(Model.hub_release == hub_release, Model.name == city_name)
|
||||
).first()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city: {err}')
|
||||
|
||||
def update(self, city_id: int, city: City):
|
||||
"""
|
||||
Updates a city
|
||||
:param city_id: the id of the city to be updated
|
||||
:param city: the city object
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
self.session.query(DBCity).filter(DBCity.id == city_id) \
|
||||
.update({
|
||||
'name': city.name, 'srs_name': city.srs_name, 'country_code': city.country_code, 'longitude': city.longitude,
|
||||
'latitude': city.latitude, 'time_zone': city.time_zone, 'lower_corner': city.lower_corner.tolist(),
|
||||
'upper_corner': city.upper_corner.tolist(), 'climate_reference_city': city.climate_reference_city,
|
||||
'updated': datetime.datetime.utcnow()
|
||||
})
|
||||
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while updating city: {err}')
|
||||
|
||||
def get_by_name(self, city_name: str) -> [DBCity]:
|
||||
def get_by_name(self, city_name: str) -> [Model]:
|
||||
"""
|
||||
Fetch city based on the name
|
||||
:param city_name: the name of the building
|
||||
:return: [ModelCity] with the provided name
|
||||
"""
|
||||
try:
|
||||
result_set = self.session.execute(select(DBCity).where(DBCity.name == city_name))
|
||||
result_set = self.session.execute(select(Model).where(Model.name == city_name))
|
||||
return [building[0] for building in result_set]
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city by name: {err}')
|
||||
|
||||
def get_by_user(self, user_id: int) -> [DBCity]:
|
||||
def get_by_user(self, user_id: int) -> [Model]:
|
||||
"""
|
||||
Fetch city based on the user who created it
|
||||
:param user_id: the id of the user
|
||||
:return: [ModelCity] with the provided name
|
||||
"""
|
||||
try:
|
||||
result_set = self.session.execute(select(DBCity).where(DBCity.user_id == user_id))
|
||||
result_set = self.session.execute(select(Model).where(Model.user_id == user_id))
|
||||
return [building[0] for building in result_set]
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city by name: {err}')
|
||||
|
||||
def update(self, city_id: int, city: CityHub):
|
||||
"""
|
||||
Updates a city name (other updates makes no sense)
|
||||
:param city_id: the id of the city to be updated
|
||||
:param city: the city object
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
now = datetime.datetime.utcnow()
|
||||
self.session.query(Model).filter(Model.id == city_id).update({'name': city.name,'updated': now})
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while updating city: {err}')
|
||||
|
||||
def delete_city(self, city_id: int):
|
||||
"""
|
||||
Deletes a City with the id
|
||||
|
@ -128,7 +128,7 @@ class CityRepo(BaseRepo):
|
|||
:return: a city
|
||||
"""
|
||||
try:
|
||||
self.session.query(DBCity).filter(DBCity.id == city_id).delete()
|
||||
self.session.query(Model).filter(Model.id == city_id).delete()
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city: {err}')
|
0
hub/persistence/repositories/city_object.py
Normal file
0
hub/persistence/repositories/city_object.py
Normal file
|
@ -1,108 +0,0 @@
|
|||
"""
|
||||
Heat pump simulation repository with database CRUD operations
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from hub.persistence import BaseRepo, CityRepo
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy import select
|
||||
from hub.persistence.models import HeatPumpSimulation
|
||||
from typing import Union, Dict
|
||||
from hub.hub_logger import logger
|
||||
|
||||
|
||||
class HeatPumpSimulationRepo(BaseRepo):
|
||||
_instance = None
|
||||
|
||||
def __init__(self, db_name, dotenv_path, app_env):
|
||||
super().__init__(db_name, dotenv_path, app_env)
|
||||
self._city_repo = CityRepo(db_name, dotenv_path, app_env)
|
||||
|
||||
def __new__(cls, db_name, dotenv_path, app_env):
|
||||
"""
|
||||
Implemented for a singleton pattern
|
||||
"""
|
||||
if cls._instance is None:
|
||||
cls._instance = super(HeatPumpSimulationRepo, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def insert(self, hp_sim_data: Dict, city_id: int) -> Union[HeatPumpSimulation, Dict]:
|
||||
"""
|
||||
Inserts the results of heat pump simulation
|
||||
:param hp_sim_data: dictionary with heatpump the simulation inputs and output
|
||||
:param city_id: the city that was used in running the simulation
|
||||
:return: HeatPumpSimulation
|
||||
"""
|
||||
|
||||
city = self._city_repo.get_by_id(city_id)
|
||||
if city is None:
|
||||
return {'message': 'city not found in database'}
|
||||
|
||||
try:
|
||||
hp_simulation = HeatPumpSimulation(city_id, hp_sim_data["HourlyElectricityDemand"],
|
||||
hp_sim_data["DailyElectricityDemand"], hp_sim_data["MonthlyElectricityDemand"],
|
||||
hp_sim_data["DailyFossilFuelConsumption"],
|
||||
hp_sim_data["MonthlyFossilFuelConsumption"])
|
||||
hp_simulation.city_id = city_id
|
||||
hp_simulation.end_year = hp_sim_data["EndYear"]
|
||||
hp_simulation.start_year = hp_sim_data["StartYear"]
|
||||
hp_simulation.max_demand_storage_hour = hp_sim_data["HoursOfStorageAtMaxDemand"]
|
||||
hp_simulation.max_hp_energy_input = hp_sim_data["MaximumHPEnergyInput"]
|
||||
hp_simulation.building_supply_temp = hp_sim_data["BuildingSuppTemp"]
|
||||
hp_simulation.temp_difference = hp_sim_data["TemperatureDifference"]
|
||||
hp_simulation.fuel_lhv = hp_sim_data["FuelLHV"]
|
||||
hp_simulation.fuel_price = hp_sim_data["FuelPrice"]
|
||||
hp_simulation.fuel_efficiency = hp_sim_data["FuelEF"]
|
||||
hp_simulation.fuel_density = hp_sim_data["FuelDensity"]
|
||||
hp_simulation.hp_supply_temp = hp_sim_data["HPSupTemp"]
|
||||
hp_simulation.simulation_type = hp_sim_data["SimulationType"]
|
||||
hp_simulation.heat_pump_model = hp_sim_data["HeatPumpModel"]
|
||||
hp_simulation.heat_pump_type = hp_sim_data["HeatPumpType"]
|
||||
|
||||
# Persist heat pump simulation data
|
||||
self.session.add(hp_simulation)
|
||||
self.session.flush()
|
||||
self.session.commit()
|
||||
return hp_simulation
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while saving heat pump simulation data: {err}')
|
||||
except KeyError as err:
|
||||
logger.error(f'A required field is missing in your heat pump simulation dictionary: {err}')
|
||||
|
||||
def get_by_id(self, hp_simulation_id: int) -> HeatPumpSimulation:
|
||||
"""
|
||||
Fetches heat pump simulation data
|
||||
:param hp_simulation_id: the city id
|
||||
:return: a HeatPumpSimulation
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(HeatPumpSimulation).where(HeatPumpSimulation.id == hp_simulation_id)).first()[
|
||||
0]
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city: {err}')
|
||||
|
||||
def get_by_city(self, city_id: int) -> [HeatPumpSimulation]:
|
||||
"""
|
||||
Fetch heat pump simulation results by city
|
||||
:param city_id: the name of the building
|
||||
:return: [HeatPumpSimulation] with the provided name
|
||||
"""
|
||||
try:
|
||||
result_set = self.session.execute(select(HeatPumpSimulation).where(HeatPumpSimulation.city_id == city_id))
|
||||
return [sim_data[0] for sim_data in result_set]
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city by name: {err}')
|
||||
|
||||
def delete_hp_simulation(self, hp_simulation_id: int):
|
||||
"""
|
||||
Deletes a heat pump simulation results
|
||||
:param hp_simulation_id: the heat pump simulation results id
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
self.session.query(HeatPumpSimulation).filter(HeatPumpSimulation.id == hp_simulation_id).delete()
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching city: {err}')
|
|
@ -5,10 +5,10 @@ Copyright © 2022 Concordia CERC group
|
|||
Project Coder Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from hub.persistence import BaseRepo
|
||||
from hub.persistence import Repository
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy import select
|
||||
from hub.persistence.models import User
|
||||
from hub.persistence.models import User as Model
|
||||
from hub.persistence.models import UserRoles
|
||||
from hub.helpers.auth import Auth
|
||||
from typing import Union, Dict
|
||||
|
@ -16,7 +16,7 @@ from hub.hub_logger import logger
|
|||
import datetime
|
||||
|
||||
|
||||
class UserRepo(BaseRepo):
|
||||
class User(Repository):
|
||||
_instance = None
|
||||
|
||||
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
|
||||
|
@ -27,14 +27,14 @@ class UserRepo(BaseRepo):
|
|||
Implemented for a singleton pattern
|
||||
"""
|
||||
if cls._instance is None:
|
||||
cls._instance = super(UserRepo, cls).__new__(cls)
|
||||
cls._instance = super(User, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def insert(self, name: str, password: str, role: UserRoles, application_id: int) -> Union[User, Dict]:
|
||||
def insert(self, name: str, password: str, role: UserRoles, application_id: int) -> Union[Model, Dict]:
|
||||
user = self.get_by_name_and_application(name, application_id)
|
||||
if user is None:
|
||||
try:
|
||||
user = User(name=name, password=Auth.hash_password(password), role=role, application_id=application_id)
|
||||
user = Model(name=name, password=Auth.hash_password(password), role=role, application_id=application_id)
|
||||
self.session.add(user)
|
||||
self.session.flush()
|
||||
self.session.commit()
|
||||
|
@ -42,38 +42,42 @@ class UserRepo(BaseRepo):
|
|||
except SQLAlchemyError as err:
|
||||
logger.error(f'An error occurred while creating user: {err}')
|
||||
else:
|
||||
return {'message': f'user with {email} email already exists'}
|
||||
return {'message': f'user {name} already exists for that application'}
|
||||
|
||||
def update(self, user_id: int, name: str, email: str, password: str, role: UserRoles) -> Union[Dict, None]:
|
||||
def update(self, user_id: int, name: str, password: str, role: UserRoles) -> Union[Dict, None]:
|
||||
"""
|
||||
Updates a user
|
||||
:param user_id: the id of the user to be updated
|
||||
:param name: the name of the user
|
||||
:param email: the email of the user
|
||||
:param password: the password of the user
|
||||
:param role: the role of the user
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
if Auth.validate_password(password):
|
||||
self.session.query(User).filter(User.id == user_id) \
|
||||
.update({'name': name, 'email': email, 'password': Auth.hash_password(password), 'role': role,
|
||||
'updated': datetime.datetime.utcnow()})
|
||||
self.session.query(Model).filter(Model.id == user_id).update({
|
||||
'name': name,
|
||||
'password': Auth.hash_password(password),
|
||||
'role': role,
|
||||
'updated': datetime.datetime.utcnow()
|
||||
})
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while updating user: {err}')
|
||||
return {'err_msg': 'Error occurred while updated user'}
|
||||
|
||||
def get_by_email(self, email: str) -> [User]:
|
||||
def get_by_name_and_application(self, name: str, application_id: int) -> [Model]:
|
||||
"""
|
||||
Fetch user based on the email address
|
||||
:param email: the email of the user
|
||||
:return: [User] with the provided email
|
||||
:param name: User name
|
||||
:param application_id: User application name
|
||||
:return: [User] matching the search criteria
|
||||
"""
|
||||
try:
|
||||
return self.session.execute(select(User).where(User.email == email)).first()
|
||||
return self.session.execute(
|
||||
select(Model).where(Model.name == name and Model.application_id == application_id)
|
||||
).first()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching user by email: {err}')
|
||||
logger.error(f'Error while fetching user by name and application: {err}')
|
||||
|
||||
def delete_user(self, user_id: int):
|
||||
"""
|
||||
|
@ -82,25 +86,27 @@ class UserRepo(BaseRepo):
|
|||
:return: None
|
||||
"""
|
||||
try:
|
||||
self.session.query(User).filter(User.id == user_id).delete()
|
||||
self.session.query(Model).filter(Model.id == user_id).delete()
|
||||
self.session.commit()
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching user: {err}')
|
||||
|
||||
def get_user_by_email_and_password(self, email: str, password: str) -> [User]:
|
||||
def get_user_by_name_application_and_password(self, name: str, password: str, application_id: int) -> [Model]:
|
||||
"""
|
||||
Fetch user based on the email and password
|
||||
:param email: the email of the user
|
||||
:param password: the password of the user
|
||||
:param name: User name
|
||||
:param password: User password
|
||||
:param application_id: User password
|
||||
|
||||
:return: [User] with the provided email and password
|
||||
"""
|
||||
try:
|
||||
user = self.session.execute(select(User).where(User.email == email)).first()
|
||||
user = self.session.execute(
|
||||
select(Model).where(Model.name == name and Model.application_id == application_id)
|
||||
).first()
|
||||
if user:
|
||||
if Auth.check_password(password, user[0].password):
|
||||
return user
|
||||
else:
|
||||
return {'message': 'Wrong email/password combination'}
|
||||
return {'message': 'user not found'}
|
||||
return {'message': 'invalid login information'}
|
||||
except SQLAlchemyError as err:
|
||||
logger.error(f'Error while fetching user by email: {err}')
|
|
@ -5,17 +5,17 @@ Copyright © 2022 Concordia CERC group
|
|||
Project Coder Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from hub.persistence.db_config import BaseConfiguration
|
||||
from hub.persistence.configuration import Configuration
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
class BaseRepo:
|
||||
class Repository:
|
||||
|
||||
def __init__(self, db_name, dotenv_path: str, app_env='TEST'):
|
||||
try:
|
||||
self.config = BaseConfiguration(db_name, dotenv_path, app_env)
|
||||
self.engine = create_engine(self.config.conn_string())
|
||||
self.configuration = Configuration(db_name, dotenv_path, app_env)
|
||||
self.engine = create_engine(self.configuration.conn_string())
|
||||
self.session = Session(self.engine)
|
||||
except ValueError as err:
|
||||
print(f'Missing value for credentials: {err}')
|
5
setup.py
5
setup.py
|
@ -13,7 +13,10 @@ setup(
|
|||
description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers "
|
||||
"to create better and sustainable cities",
|
||||
long_description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help "
|
||||
"researchers to create better and sustainable cities",
|
||||
"researchers to create better and sustainable cities.\n\nDevelop at Concordia university in canada "
|
||||
"as part of the research group from the next generation cities institute our aim among others it's "
|
||||
"to provide a comprehensive set of tools to help researchers and urban developers to make decisions "
|
||||
"to improve the livability and efficiency of our cities",
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
|
|
Loading…
Reference in New Issue
Block a user