-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
FastAPI response model issue with SQLalchemy 1.4 #2124
Copy link
Copy link
Closed
Labels
bug V1Bug related to Pydantic V1.XBug related to Pydantic V1.X
Description
Checks
- I added a descriptive title to this issue
- I have searched (google, github) for similar issues and couldn't find anything
- I have read and followed the docs and still think this is a bug
Not sure if this is the correct place for this, if not please notify where it would be better suited.
Bug
When using SQLAlchemy 1.3 with FastAPI and pydantic you could do this:
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
class UserBase(BaseModel):
email: str
class User(UserBase):
id: int
is_active: bool
items: List[Item] = []
class Config:
orm_mode = True
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return usersThe result as expected is as follows:
[
{
"email": "string",
"id": 1,
"is_active": true,
"items": []
}
]But when you upgrade to SQLAlchemy 1.4 the response_model breaks.
async def get_users(db: AsyncSession, skip: int = 0, limit: int = 100):
db_execute = await db.execute(select(models.User).offset(skip).limit(limit))
return db_execute.all()
@app.get("/users/", response_model=List[schemas.User])
async def read_users(skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db)):
crud_users = await crud.get_users(db, skip=skip, limit=limit)
return crud_usersINFO: 127.0.0.1:60298 - "GET /users/?skip=0&limit=100 HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 389, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/fastapi/applications.py", line 179, in __call__
await super().__call__(scope, receive, send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/fastapi/routing.py", line 190, in app
response_data = await serialize_response(
File "/Users/user/code-utils/test_env/lib/python3.9/site-packages/fastapi/routing.py", line 111, in serialize_response
raise ValidationError(errors, field.type_)
pydantic.error_wrappers.ValidationError: 6 validation errors for User
response -> 0 -> email
field required (type=value_error.missing)
response -> 0 -> id
field required (type=value_error.missing)
response -> 0 -> is_active
field required (type=value_error.missing)
response -> 1 -> email
field required (type=value_error.missing)
response -> 1 -> id
field required (type=value_error.missing)
response -> 1 -> is_active
field required (type=value_error.missing)A quick fix I found:
async def get_users(db: AsyncSession, skip: int = 0, limit: int = 100):
db_execute = await db.execute(select(models.User).offset(skip).limit(limit))
return_items = []
for item in db_execute.all():
return_items.append(item[0].__dict__)
return return_itemsEntire example can be found here: fastapi/fastapi#2331
Again I'm not sure if this is the correct repository for this, so please notify where would it be better suited.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bug V1Bug related to Pydantic V1.XBug related to Pydantic V1.X