You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Pydantic create_model动态定义可用作ORM的SQLModel类

如何用Pydantic的create_model创建功能完整的SQLModel类

结论

可以实现,只要在动态创建模型时正确继承SQLModel,并补充ORM所需的元数据配置,就能让动态模型拥有和静态定义的SQLModel完全一致的ORM功能。

实现步骤与代码示例

下面是构建与示例中Hero模型功能完全等效的动态模型,并完成数据库增查操作的代码:

1. 导入依赖

from typing import Optional, Dict, Any
from sqlmodel import Field, SQLModel, Session, create_engine
from pydantic import create_model

2. 动态构建SQLModel类

def build_dynamic_hero_model() -> type[SQLModel]:
    # 定义字段映射,对应静态模型的每个字段类型与约束
    field_definitions: Dict[str, Any] = {
        "id": (Optional[int], Field(default=None, primary_key=True)),
        "name": (str, ...),  # ... 表示必填字段,对应静态模型中的str类型无默认值
        "secret_name": (str, ...),
        "age": (Optional[int], None)
    }
    
    # 创建动态模型,核心是指定继承SQLModel,并设置表相关参数
    DynamicHero = create_model(
        "DynamicHero",
        __base__=SQLModel,
        __table_args__={"extend_existing": True},  # 避免重复注册表时抛出错误
        **field_definitions
    )
    
    # 触发SQLModel的元数据同步,确保表被创建
    engine = create_engine("sqlite:///test.db")
    SQLModel.metadata.create_all(engine)
    
    return DynamicHero

3. 测试ORM功能

if __name__ == "__main__":
    # 获取动态模型
    DynamicHero = build_dynamic_hero_model()
    
    # 初始化数据库连接
    engine = create_engine("sqlite:///test.db", echo=True)  # echo=True可以查看SQL日志
    SQLModel.metadata.create_all(engine)
    
    # 执行数据库操作
    with Session(engine) as session:
        # 创建并添加实例
        new_hero = DynamicHero(name="蝙蝠侠", secret_name="布鲁斯·韦恩", age=35)
        session.add(new_hero)
        session.commit()
        session.refresh(new_hero)
        print(f"新增英雄ID: {new_hero.id}")
        
        # 查询验证
        fetched_hero = session.get(DynamicHero, new_hero.id)
        print(f"查询到英雄: {fetched_hero.name} - 秘密身份: {fetched_hero.secret_name}")

关键注意事项

  • 必须继承SQLModel:通过__base__=SQLModel让动态模型获得SQLModel的ORM能力,否则只是普通的Pydantic模型,无法和数据库交互。
  • 表重复注册防护:设置__table_args__={"extend_existing": True},避免多次调用动态模型创建函数时,因表已存在而报错。
  • 元数据手动同步:静态定义的SQLModel会在导入时自动注册元数据,但动态模型需要手动调用SQLModel.metadata.create_all()来确保表被创建。
  • 字段约束匹配:字段的类型、默认值、Field参数(如primary_key=True)必须和静态模型完全一致,才能保证功能等效。

扩展说明

如果需要创建带关联关系的动态SQLModel,需要额外处理关联字段的Relationship配置,确保SQLAlchemy的关系元数据被正确添加到动态模型中,核心逻辑和上述示例一致,只需在字段定义中加入Relationship相关配置即可。

内容的提问来源于stack exchange,提问作者Daniel Fainberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:10:20