base_model.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. from datetime import datetime
  2. from typing import Optional
  3. import orjson
  4. from sqlalchemy import DateTime, text
  5. from sqlalchemy.orm import declared_attr
  6. from sqlmodel import SQLModel, Field
  7. from app.libs.types import ObjectId
  8. from app.libs.util import datetime2timestamp
  9. def orjson_dumps(v, *, default):
  10. # orjson.dumps returns bytes, to match standard json.dumps we need to decode
  11. return orjson.dumps(v, default=default).decode()
  12. def to_snake_case(string: str) -> str:
  13. return "".join(["_" + i.lower() if i.isupper() else i for i in string]).lstrip("_")
  14. class BaseModel(SQLModel):
  15. class Config:
  16. from_attributes = True
  17. populate_by_name = True
  18. json_encoders = {
  19. datetime: lambda v: datetime2timestamp(v),
  20. }
  21. @classmethod
  22. @declared_attr
  23. def __tablename__(cls) -> str:
  24. return to_snake_case(cls.__name__)
  25. class TimeStampMixin(SQLModel):
  26. created_at: Optional[datetime] = Field(
  27. sa_type=DateTime,
  28. default=None,
  29. nullable=False,
  30. sa_column_kwargs={"server_default": text("CURRENT_TIMESTAMP")},
  31. )
  32. updated_at: Optional[datetime] = Field(
  33. sa_type=DateTime,
  34. default=None,
  35. sa_column_kwargs={"onupdate": text("CURRENT_TIMESTAMP")},
  36. )
  37. class PrimaryKeyMixin(SQLModel):
  38. id: str = Field(primary_key=True, default_factory=ObjectId)