Python可否继承类型注解以抽象SQLModel通用CRUD模型结构?
解决方案
完全可以通过Python的泛型+类工厂模式实现代码复用,你只需要编写一次通用模板,后续每个模型仅需定义核心业务字段,即可自动生成配套的表模型、Create、Read、Update类,无需重复编写冗余结构。
通用实现代码
首先编写可复用的CRUD模型生成工厂:
from typing import Optional, Type, TypeVar from sqlmodel import Field, SQLModel T = TypeVar("T", bound=SQLModel) def generate_crud_models( base_class: Type[T], ) -> tuple[Type[T], Type[T], Type[T], Type[T]]: """ 输入仅包含业务字段的基类,自动生成CRUD全量模型 返回顺序:表模型、创建请求模型、读取返回模型、更新请求模型 """ # 数据库表模型:继承基础字段 + 主键id class TableModel(base_class, table=True): id: Optional[int] = Field(default=None, primary_key=True) # 创建模型:直接继承基础字段,无额外逻辑 class CreateModel(base_class): pass # 读取模型:基础字段 + 必返回id class ReadModel(base_class): id: int # 更新模型:所有基础字段自动设为可选,默认值为None update_annotations = {} for field_name, field_info in base_class.model_fields.items(): update_annotations[field_name] = (Optional[field_info.annotation], None) UpdateModel = type(f"{base_class.__name__}Update", (SQLModel,), update_annotations) return TableModel, CreateModel, ReadModel, UpdateModel
使用示例
以你提到的Room模型为例,现在仅需编写核心业务字段,一行代码即可生成所有CRUD需要的模型:
from typing import Optional, List from sqlmodel import Field, Relationship # 仅定义业务相关的核心字段即可 class RoomBase(SQLModel): name: str is_ensuite: bool current_occupants: Optional[List[str]] house_id: Optional[int] = Field(default=None, foreign_key="house.id") # 一键生成全量CRUD模型,类名可以按自己的命名习惯调整 Room, RoomCreate, RoomRead, RoomUpdate = generate_crud_models(RoomBase) # 如果需要配置模型关联关系,额外补充即可 Room.house = Optional["House"] = Relationship(back_populates="rooms")
拓展说明
- 该方案兼容SQLModel 0.0.8及以上版本,生成的模型和手动编写的完全等价,支持FastAPI参数校验、数据库增删改查所有原生功能
- 如果有特殊场景需要自定义某类模型的字段,直接继承生成的对应类修改即可,无需重写全部逻辑
- 可以根据自身业务需求修改工厂逻辑,比如统一添加创建时间、更新时间等公共字段,适配更多场景
内容的提问来源于stack exchange,提问作者John Kealy
相关产品推荐
相关产品推荐

