model.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from datetime import datetime
  4. from typing import Annotated
  5. from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, declared_attr, mapped_column
  6. from utils.timezone import timezone
  7. # 通用 Mapped 类型主键, 需手动添加,参考以下使用方式
  8. # MappedBase -> id: Mapped[id_key]
  9. # DataClassBase && Base -> id: Mapped[id_key] = mapped_column(init=False)
  10. id_key = Annotated[
  11. int, mapped_column(primary_key=True, index=True, autoincrement=True, sort_order=-999, comment='主键id')
  12. ]
  13. id_key_str = Annotated[
  14. str, mapped_column(primary_key=True, index=True, sort_order=-999, comment='主键id')
  15. ]
  16. # Mixin: 一种面向对象编程概念, 使结构变得更加清晰, `Wiki <https://en.wikipedia.org/wiki/Mixin/>`__
  17. class UserMixin(MappedAsDataclass):
  18. """用户 Mixin 数据类"""
  19. create_user: Mapped[int] = mapped_column(sort_order=998, comment='创建者')
  20. update_user: Mapped[int | None] = mapped_column(init=False, default=None, sort_order=998, comment='修改者')
  21. class DateTimeMixin(MappedAsDataclass):
  22. """日期时间 Mixin 数据类"""
  23. created_at: Mapped[datetime] = mapped_column(
  24. init=False, default_factory=timezone.now, sort_order=999, comment='创建时间'
  25. )
  26. updated_at: Mapped[datetime | None] = mapped_column(
  27. init=False, onupdate=timezone.now, sort_order=999, comment='更新时间'
  28. )
  29. class MappedBase(DeclarativeBase):
  30. """
  31. 声明性基类, 原始 DeclarativeBase 类, 作为所有基类或数据模型类的父类而存在
  32. `DeclarativeBase <https://docs.sqlalchemy.org/en/20/orm/declarative_config.html>`__
  33. `mapped_column() <https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.mapped_column>`__
  34. """
  35. @declared_attr.directive
  36. def __tablename__(cls) -> str:
  37. return cls.__name__.lower()
  38. class DataClassBase(MappedAsDataclass, MappedBase):
  39. """
  40. 声明性数据类基类, 它将带有数据类集成, 允许使用更高级配置, 但你必须注意它的一些特性, 尤其是和 DeclarativeBase 一起使用时
  41. `MappedAsDataclass <https://docs.sqlalchemy.org/en/20/orm/dataclasses.html#orm-declarative-native-dataclasses>`__
  42. """ # noqa: E501
  43. __abstract__ = True
  44. class Base(DataClassBase, DateTimeMixin):
  45. """
  46. 声明性 Mixin 数据类基类, 带有数据类集成, 并包含 MiXin 数据类基础表结构, 你可以简单的理解它为含有基础表结构的数据类基类
  47. """ # noqa: E501
  48. __abstract__ = True