Data Mastery
Data Mastery

Reputation: 2095

FastAPI - GET request results in typeerror (value is not a valid dict)

this is my database schema.

enter image description here

I defined my Schema like this:

from pydantic import BaseModel

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

This is my model:

class Userattribute(Base):
    __tablename__ = "user_attribute"

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

In a crud.py I define a get_attributes method.

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

This is my GET endpoint:

@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

The connection to the database seems to work, but a problem is the datatype:

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)

Why does FASTApi expect a dictionary here? I don´t really understand it, since I am not able to even print the response. How can I fix this?

Upvotes: 34

Views: 60765

Answers (2)

MatsLindh
MatsLindh

Reputation: 52892

Pydantic 2 changed how models gets configured, so if you're using the most recent version of Pydantic, see the section named Pydantic 2 below.

SQLAlchemy does not return a dictionary, which is what pydantic expects by default. You can configure your model to also support loading from standard orm parameters (i.e. attributes on the object instead of dictionary lookups):

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

    class Config:
        orm_mode = True

You can also attach a debugger right before the call to return to see what's being returned.

Since this answer has become slightly popular, I'd like to also mention that you can make orm_mode = True the default for your schema classes by having a common parent class that inherits from BaseModel:

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


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

This is useful if you want to support orm_mode for most of your classes (and for those where you don't, inherit from the regular BaseModel).

Pydantic 2

Pydantic 2 has replaced the internal Config class with a model_config field:

from pydantic import ConfigDict

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

This works in the same way as the old orm_mode.

Upvotes: 81

Bello Shehu
Bello Shehu

Reputation: 345

This error is caused by two things:

  1. The reponse_model parameter in the path operation decorator, which defines the type/shape of response to be returned. Removing this will eliminate the errors you see, as it will remove the validation against what is being returned.

  2. The internal Config class that is missing in your Pydantic schemas.

Make sure to add the Config class to avoid this problem, or at worst, remove the response_model parameter (which I doubt anyone would consider). Example is:

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

    class Config:
        orm_mode = True

Adding this class allows Pydantic model to read data in non-dictionary format, thereby allowing you to return database model.

Checkout the fastAPI documentation for more

Upvotes: 1

Related Questions