如何将 JSON 列与 SQLModel 结合使用

dan*_*wos 22 json sqlalchemy sqlmodel

我正在尝试通过 SQLModel 定义 JSON 列:

from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, JSON


class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: Optional[int] = None
    meta: JSON
Run Code Online (Sandbox Code Playgroud)

代码来自SQLModel,但通过“meta”属性进行扩展。

将上面的代码与示例代码的其余部分(设置 sqlite、添加数据)一起使用,出现以下错误:

RuntimeError: no validator found for <class 'sqlalchemy.sql.sqltypes.JSON'>, see `arbitrary_types_allowed` in Config
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下方式扩展代码

class Hero(SQLModel, table=True):
    [...]
    meta: JSON

    @validator('meta')
    def validate_json(v):
        return v

    class Config:
        arbitrary_types_allowed = True 
Run Code Online (Sandbox Code Playgroud)

但这会导致另一个错误:

sqlalchemy.exc.CompileError: (in table 'hero', column 'meta'): Can't generate DDL for NullType(); did you forget to specify a type on this Column?
Run Code Online (Sandbox Code Playgroud)

我仅使用 SQLAlchemy 进行了尝试,并且成功了。

那么有什么想法如何才能在 SQLModel 和 SQLAlchemy 之间完成 JSON 字段的“连接”吗?

更新:我还测试过将其设置为可选并给它一个默认值。没有成功(2.再次出错):

class Hero(SQLModel, table=True):
    [...]
    meta: Optional[JSON] = {}

    class Config:
        arbitrary_types_allowed = True 
Run Code Online (Sandbox Code Playgroud)

小提示:即使JSON是从 导入的SQLModel,最终也是从 导入的,SQLAlchemy.sqltypes没有任何改变。

Get*_*fix 20

我相信您正在寻找的连接可能是由sa_columnField 的参数提供的,例如:

class Hero(SQLModel, table=True):
    [...]

    meta: Dict = Field(default={}, sa_column=Column(JSON))

    # Needed for Column(JSON)
    class Config:
        arbitrary_types_allowed = True
Run Code Online (Sandbox Code Playgroud)

  • random_types_allowed 似乎不是强制性的,在 sqlmodel 0.0.8 下没有它也可以工作 (3认同)