首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何动态定义SQLModel类

如何动态定义SQLModel类
EN

Stack Overflow用户
提问于 2022-10-24 20:25:54
回答 1查看 49关注 0票数 0

上下文

SQLModel在很大程度上基于Pydantic。后者具有create_model函数,允许您在运行时创建/定义模型类,方法是将字段定义作为任意关键字参数传递。

create_model中似乎没有内置到SQLModel中的特殊版本,文档中也没有提到动态模型的创建。

问题

可以利用Pydantic create_model函数来定义一个功能齐全的SQLModel类吗?

要求

在某种意义上,它将正确地充当ORM类,使用数据库引擎发挥作用,它的实例可以添加到数据库会话中并由数据库会话刷新,就像任何静态定义的SQLModel子类一样。

作为概念的证明,应该可以动态地构造以下静态定义模型的等效工作,并使用它执行上述操作:

代码语言:javascript
复制
from typing import Optional

from sqlmodel import Field, SQLModel

class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: Optional[int] = None
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-24 20:25:54

答案是肯定的!

create_model函数具有可选的__base__参数(如文档中提到的),它接受Pydantic BaseModel的任何子类(或子类序列)。SQLModel基类恰好是直接从BaseModel继承的,因此可以在这里传递。

但是,这不足以使模型映射到SQLModelMetaclass要求table=True作为关键字参数在SQLModel子类中传递。幸运的是,在Pydantic中也有一个解决方案。

虽然Pydantic的文档网站上没有提到这一点,但是create_model函数(来源在这里)有一个__cls_kwargs__参数,可以在类创建期间将任意关键字参数传递给元类。

这两个组件以及实际的字段定义实际上都是我们动态创建ORM类所需要的。下面是一个完整的工作示例:

代码语言:javascript
复制
from typing import Optional

from pydantic import create_model
from sqlmodel import Field, Session, SQLModel, create_engine

field_definitions = {
    "id": (Optional[int], Field(default=None, primary_key=True)),
    "name": (str, ...),
    "secret_name": (str, ...),
    "age": (Optional[int], None),
}

Hero = create_model(
    "Hero",
    __base__=SQLModel,
    __cls_kwargs__={"table": True},
    **field_definitions,
)

if __name__ == '__main__':
    sqlite_url = "sqlite:///test.db"
    engine = create_engine(sqlite_url, echo=True)
    SQLModel.metadata.create_all(engine)
    session = Session(engine)
    hero = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
    session.add(hero)
    session.commit()
    session.refresh(hero)
    print(hero)

print语句提供以下输出:

代码语言:javascript
复制
secret_name='Pedro Parqueador' id=1 age=None name='Spider-Boy'

这说明id是在插入时由数据库创建的。

引擎打印到stdout的SQL语句显示,一切按计划进行:

代码语言:javascript
复制
CREATE TABLE hero (
    id INTEGER NOT NULL, 
    name VARCHAR NOT NULL, 
    secret_name VARCHAR NOT NULL, 
    age INTEGER, 
    PRIMARY KEY (id)
)

...

INSERT INTO hero (name, secret_name, age) VALUES (?, ?, ?)
('Spider-Boy', 'Pedro Parqueador', None)

...

SELECT hero.id, hero.name, hero.secret_name, hero.age 
FROM hero 
WHERE hero.id = ?
(1,)

到目前为止,除了适用于Pydantic中的动态模型创建之外,我还没有遇到对这种方法的任何警告,例如,如果模型是动态定义的,那么显然缺乏静态类型检查支持或自动建议。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74186458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档