this is my database schema.
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?
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
.