"""base sqlalchemy model.""" from fastapi import HTTPException from moneyhub.connectors.mysql import Base from moneyhub.connectors.mysql import db from moneyhub.constants.error import ENTITY_DOES_NOT_EXIST class CRUDMixin: """CRUD model mixin.""" @classmethod def get_by_id(cls, obj_id: int) -> object: """Get object from DB by ID property. Args: obj_id (int): Id of the db record Returns: object: record object """ return cls.query.get(obj_id) @classmethod def get_by_id_or_error(cls, obj_id: int) -> object: """Find object by ID. Raise exception if not found. Args: obj_id (int): Id of the db record Returns: object: record object """ obj = cls.get_by_id(obj_id) if obj is None: raise HTTPException( detail=ENTITY_DOES_NOT_EXIST.format( object_type=cls.__name__, object_id=obj_id ), status_code=404 ) return obj @classmethod def create(cls, **kwargs: dict) -> object: """Persist a new object. Args: kwargs (dict): POST request body Returns: object: newly created record object """ new_object = cls.build(**kwargs) db.session.commit() return new_object @classmethod def build(cls, **kwargs: dict) -> object: """Construct a new object without persisting it. Args: kwargs (dict): POST request body Returns: object: newly created record object """ new_object = cls(**kwargs) db.session.add(new_object) return new_object @staticmethod def commit_changes(*new_objects: object): """Commit the session, adding any new objects if necessary.""" if new_objects: db.session.add_all(new_objects) db.session.commit() def to_dict(self) -> dict: """Convert the object into a dictionary. Returns: dict: The contents as a dictionary. """ the_dict = dict(self.__dict__) the_dict.pop('_sa_instance_state', None) return the_dict def update_attributes(self, **attrs: dict): """Update attributes. Args: attrs (dict): PUT request body """ for key, val in attrs.items(): setattr(self, key, val) return self class BaseModel(Base, CRUDMixin): """Base model.""" def __init__(self, *args, **kwargs): """Initialize model with default values.""" super().__init__(*args, **kwargs) __abstract__ = True