I tried a bunch of methods to fix this error but I still don’t understand what the problem is.
router:
@router.get('', response_model=List[SProject])
async def get_all_projects():
return await ProjectDAO.find_all()
models:
class ProjectProfile(Base):
__tablename__ = 'project_profile'
project_id = Column(ForeignKey('projects.id'), primary_key=True)
profile_id = Column(ForeignKey('profiles.id'), primary_key=True)
role = Column('role', String)
is_creator = Column(Boolean, default=False)
class Project(Base):
__tablename__ = 'projects'
id = Column(Integer, primary_key=True)
title = Column(String, nullable=False)
description = Column(String)
created_at = Column(Date, default=datetime.utcnow())
profiles = relationship('Profile', secondary='project_profile',
back_populates='projects')
schemas:
class SProject(BaseModel):
id: int
title: str
description: Optional[str] = None
created_at: Optional[datetime] = None
class Config:
orm_mode = True
dao:
class ProjectDAO(BaseDAO):
model = Project
@classmethod
async def find_all(cls):
async with async_session_maker() as session:
query = select(cls.model)
result = await session.execute(query)
return result.mappings().all()
response:
raise ResponseValidationError(
fastapi.exceptions.ResponseValidationError: 2 validation errors:
{'type': 'missing', 'loc': ('response', 0, 'id'), 'msg': 'Field required', 'input': {'Project': <app.projects.models.Project object at 0x7f6d5dc95e40>}, 'url': 'https://errors.pydantic.dev/2.3/v/missing'}
{'type': 'missing', 'loc': ('response', 0, 'title'), 'msg': 'Field required', 'input': {'Project': <app.projects.models.Project object at 0x7f6d5dc95e40>}, 'url': 'https://errors.pydantic.dev/2.3/v/missing'}
If I remove the SProject scheme from the router, it returns data normally
Like this
router:
@router.get('')
async def get_all_projects():
return await ProjectDAO.find_all()
response:
[
{
"Project": {
"created_at": "2023-09-20",
"id": 2,
"description": "sdadasd",
"title": "dasd"
}
}
]
You are getting this error because according to your response model, the response should be in the format
[
{
"created_at": "2023-09-20",
"id": 2,
"description": "sdadasd",
"title": "dasd"
}
]
You are returning this nested in a "Project" object
[
{
"Project": {
"created_at": "2023-09-20",
"id": 2,
"description": "sdadasd",
"title": "dasd"
}
}
]
That's the way sqlalchemy's mappings().all()
returns the dictionary.
If you want the response like this, you can solve this error by changing your response model
class SProject(BaseModel):
id: int
title: str
description: Optional[str] = None
created_at: Optional[datetime] = None
class Config:
orm_mode = True
class SProjectResponse(BaseModel):
Project: SProject = Field()
And you set List[SProjectResponse]
as your response model
@router.get('', response_model=List[SProjectResponse])
async def get_all_projects():
return await ProjectDAO.find_all()