#!/usr/bin/env python3 # -*- coding: utf-8 -*- from datetime import datetime from typing import Annotated from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, declared_attr, mapped_column from utils.timezone import timezone # 通用 Mapped 类型主键, 需手动添加,参考以下使用方式 # MappedBase -> id: Mapped[id_key] # DataClassBase && Base -> id: Mapped[id_key] = mapped_column(init=False) id_key = Annotated[ int, mapped_column(primary_key=True, index=True, autoincrement=True, sort_order=-999, comment='主键id') ] id_key_str = Annotated[ str, mapped_column(primary_key=True, index=True, sort_order=-999, comment='主键id') ] # Mixin: 一种面向对象编程概念, 使结构变得更加清晰, `Wiki `__ class UserMixin(MappedAsDataclass): """用户 Mixin 数据类""" create_user: Mapped[int] = mapped_column(sort_order=998, comment='创建者') update_user: Mapped[int | None] = mapped_column(init=False, default=None, sort_order=998, comment='修改者') class DateTimeMixin(MappedAsDataclass): """日期时间 Mixin 数据类""" created_at: Mapped[datetime] = mapped_column( init=False, default_factory=timezone.now, sort_order=999, comment='创建时间' ) updated_at: Mapped[datetime | None] = mapped_column( init=False, onupdate=timezone.now, sort_order=999, comment='更新时间' ) class MappedBase(DeclarativeBase): """ 声明性基类, 原始 DeclarativeBase 类, 作为所有基类或数据模型类的父类而存在 `DeclarativeBase `__ `mapped_column() `__ """ @declared_attr.directive def __tablename__(cls) -> str: return cls.__name__.lower() class DataClassBase(MappedAsDataclass, MappedBase): """ 声明性数据类基类, 它将带有数据类集成, 允许使用更高级配置, 但你必须注意它的一些特性, 尤其是和 DeclarativeBase 一起使用时 `MappedAsDataclass `__ """ # noqa: E501 __abstract__ = True class Base(DataClassBase, DateTimeMixin): """ 声明性 Mixin 数据类基类, 带有数据类集成, 并包含 MiXin 数据类基础表结构, 你可以简单的理解它为含有基础表结构的数据类基类 """ # noqa: E501 __abstract__ = True