FastAPI - GET请求导致类型错误(值不是有效的字典)

32

这是我的数据库架构。

输入图片描述

我像这样定义了我的架构:

from pydantic import BaseModel

class Userattribute(BaseModel):
    name: str
    value: str
    user_id: str
    id: str

这是我的模型:

class Userattribute(Base):
    __tablename__ = "user_attribute"

    name = Column(String)
    value = Column(String)
    user_id = Column(String)
    id = Column(String, primary_key=True, index=True)

在 crud.py 文件中,我定义了一个名为 get_attributes 的方法。

def get_attributes(db: Session, skip: int = 0, limit: int = 100):
    return db.query(models.Userattribute).offset(skip).limit(limit).all()

这是我的GET端点:

@app.get("/attributes/", response_model=List[schemas.Userattribute])
def read_attributes(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    users = crud.get_attributes(db, skip=skip, limit=limit)
    print(users)
    return users

连接到数据库似乎有效,但问题在于数据类型:

pydantic.error_wrappers.ValidationError: 7 validation errors for Userattribute
response -> 0
  value is not a valid dict (type=type_error.dict)
response -> 1
  value is not a valid dict (type=type_error.dict)
response -> 2
  value is not a valid dict (type=type_error.dict)
response -> 3
  value is not a valid dict (type=type_error.dict)
response -> 4
  value is not a valid dict (type=type_error.dict)
response -> 5
  value is not a valid dict (type=type_error.dict)
response -> 6
  value is not a valid dict (type=type_error.dict)

为什么FASTApi在这里期望一个字典?我真的不太理解,因为我甚至无法打印响应。我该如何解决这个问题?

2个回答

76

Pydantic 2改变了模型的配置方式,因此如果您正在使用最新版本的Pydantic,请查看下面的名为Pydantic 2的部分。

SQLAlchemy不会默认返回一个字典,而这是pydantic所期望的。您可以配置您的模型以支持从标准orm参数加载(即从对象的属性而不是字典查找进行加载):

class Userattribute(BaseModel):
    name: str
    value: str
    user_id: str
    id: str

    class Config:
        orm_mode = True

您还可以在调用return之前附加一个调试器,以查看返回的内容。

由于这个答案已经有些受欢迎,我想提醒您,您可以通过让一个共同的父类继承自BaseModel,将orm_mode = True设为模式类的默认值:

class OurBaseModel(BaseModel):
    class Config:
        orm_mode = True


class Userattribute(OurBaseModel):
    name: str
    value: str
    user_id: str
    id: str

这对于大多数类支持orm_mode很有用(对于那些不需要的类,可以继承自常规的BaseModel)。
Pydantic 2已经用model_config字段替换了内部的Config类。
from pydantic import ConfigDict

class OurBaseModel(BaseModel):
    model_config = ConfigDict(from_attributes=True)

这与旧的orm_mode的工作方式相同。

4
感谢您的询问。在我的情况下,我从另一个开发人员那里得到了代码,他在 class config: 中打错了单词。 - Chirag Purohit
1
在我的父类中使用 orm_mode 解决了它...谢谢。 - joeyagreco

1

这个错误是由两个原因引起的:

  1. 路径操作装饰器中的 reponse_model 参数定义了要返回的响应类型/形状。删除此参数将消除您看到的错误,因为它将消除对返回内容的验证。

  2. 您的 Pydantic 模式中缺少内部 Config 类。

确保添加 Config 类以避免此问题,或者最坏的情况下,删除 response_model 参数(我怀疑任何人都会考虑这种情况)。示例:

class ItemBase(BaseModel):
    title: str
    description: Union[str, None] = None

    class Config:
        orm_mode = True

添加这个类可以让 Pydantic 模型以非字典格式读取数据,从而允许您返回数据库模型。
查看 fastAPI 文档 了解更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接