如何在SQLModel中使用JSON列

hmmo2u0o  于 2023-05-02  发布在  其他
关注(0)|答案(2)|浏览(203)

我尝试通过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

代码来自SQLModel,但由“ meta”属性扩展。
使用上面的代码和其余的示例代码(设置sqlite,添加数据),我得到以下错误:

RuntimeError: no validator found for <class 'sqlalchemy.sql.sqltypes.JSON'>, see `arbitrary_types_allowed` in Config

我试着扩展代码

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

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

    class Config:
        arbitrary_types_allowed = True

但这会导致另一个错误:

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

我只使用SQLAlchemy尝试了一下,它已经工作了。
那么,对于JSON字段,我如何在SQLModel和SQLAlchemy之间建立“连接”呢?

更新:我也测试了可选,默认。没有成功(2.再次出错):

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

    class Config:
        arbitrary_types_allowed = True

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

mec1mxoz

mec1mxoz1#

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

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

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

    # Needed for Column(JSON)
    class Config:
        arbitrary_types_allowed = True
insrf1ej

insrf1ej2#

使用pydantic BaseModel,你可以这样做。..

# schema.py
from pydantic import BaseModel, Field

class YourSchema(BaseModel):
    """normal BaseModel schema for your data"""
    username: str = Field(example="geminixiang")
    data: dict = Field(default={}, example={"foo": "bardata"})

# model.py
from schema import YourSchema
from typing import Optional
from sqlalchemy import JSON, Column
from sqlmodel import Field, SQLModel

class ForDBModel(SQLModel, YourSchema, table=True):
    """when you use it for db orm"""
    id: Optional[int] = Field(default=None, primary_key=True)
    # overwrite `dict` field
    data: dict = Field(sa_column=Column(JSON), default={})

相关问题