base.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. from __future__ import annotations
  2. import datetime
  3. import typing as T
  4. from flask import abort
  5. from sqlalchemy_serializer import SerializerMixin
  6. from pycs import app
  7. from pycs import db
  8. from pycs.database.util import commit_on_return
  9. class BaseModel(db.Model, SerializerMixin):
  10. __abstract__ = True
  11. # setup of the SerializerMixin
  12. date_format = '%s' # Unixtimestamp (seconds)
  13. datetime_format = '%d. %b. %Y %H:%M:%S'
  14. time_format = '%H:%M'
  15. id = db.Column(db.Integer, primary_key=True)
  16. serialize_only = ("id",)
  17. def __repr__(self):
  18. attrs = self.serialize()
  19. content = ", ".join([f"{attr}={value}" for attr, value in attrs.items()])
  20. return f"<{self.__class__.__name__}: {content}>"
  21. def serialize(self) -> dict:
  22. return self.to_dict()
  23. @commit_on_return
  24. def delete(self) -> dict:
  25. """
  26. delete this instance from the database
  27. :return: serialized self
  28. """
  29. db.session.delete(self)
  30. dump = self.serialize()
  31. return dump
  32. # do an alias
  33. remove = delete
  34. @classmethod
  35. def new(cls, commit: bool = True, **kwargs):
  36. obj = cls(**kwargs)
  37. db.session.add(obj)
  38. if commit:
  39. self.commit()
  40. @classmethod
  41. def get_or_create(cls, **kwargs) -> T.Tuple[BaseModel, bool]:
  42. is_new = False
  43. obj = cls.query.filter_by(**kwargs).one_or_none()
  44. if obj is None:
  45. obj = cls.new(commit=False, **kwargs)
  46. is_new = True
  47. return obj, is_new
  48. @classmethod
  49. def get_or_404(cls, obj_id: int) -> BaseModel:
  50. obj = cls.query.get(obj_id)
  51. if obj is None:
  52. abort(404, f"{cls.__name__} with ID {obj_id} could not be found!")
  53. return obj
  54. def commit(self):
  55. db.session.commit()
  56. def flush(self):
  57. db.session.flush()
  58. class NamedBaseModel(BaseModel):
  59. __abstract__ = True
  60. name = db.Column(db.String, nullable=False)
  61. serialize_only = BaseModel.serialize_only + ("name",)
  62. @commit_on_return
  63. def set_name(self, name: str):
  64. self.name = name