uriyyo / fastapi-pagination

FastAPI pagination 📖
https://uriyyo-fastapi-pagination.netlify.app/
MIT License
1.19k stars 136 forks source link

Validation error when selecting single field with SQLModel #1244

Closed savvan0h closed 1 month ago

savvan0h commented 3 months ago

I encountered a validation error when querying only a single field from a model using SQLModel. The error occurs when using the following code:

from fastapi_pagination.ext.sqlmodel import paginate
from sqlmodel import SQLModel

class User(SQLModel):
    name: str

@router.get("/users", response_model=Page[User])
def get_users(session: SessionDep):
    return paginate(session, select(User.name))
...
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/ext/sqlmodel.py", line 121, in paginate
    return _paginate(
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/ext/sqlalchemy.py", line 283, in paginate
    return exec_pagination(
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/ext/sqlalchemy.py", line 186, in exec_pagination
    return create_page(
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/api.py", line 182, in create_page
    return _page_val.get().create(items, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/default.py", line 73, in create
    return create_pydantic_model(
  File "/usr/local/lib/python3.10/site-packages/fastapi_pagination/utils.py", line 171, in create_pydantic_model
    return model_cls.model_validate(kwargs, from_attributes=True)  # type: ignore
  File "/usr/local/lib/python3.10/site-packages/pydantic/main.py", line 509, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 50 validation errors for Page[User]
items.0
  Input should be a valid dictionary or object to extract fields from [type=model_attributes_type, input_value='...', input_type=str]
    For further information visit https://errors.pydantic.dev/2.6/v/model_attributes_type
...

The issue seems to stem from the unwrap_scalars() function in ext/sqlalchemy.py, which converts the result items to strings when a single field is selected.

https://github.com/uriyyo/fastapi-pagination/blob/139f4eea477d7d86879452e939023b77df21c7c9/fastapi_pagination/ext/sqlalchemy.py#L183

To work around this issue, I had to manually transform the items into dictionaries like below:

paginate(session, select(User.name), transformer=lambda items: [{'name': item} for item in items])

Given that both SQLAlchemy and SQLModel share the same code, it is likely that this issue affects SQLAlchemy as well.

uriyyo commented 2 months ago

Hi @savvan0h,

Thanks for the issue, I will think about how we can fix it.

uriyyo commented 1 month ago

Hi @savvan0h,

New version 0.12.28 has been released, and now your code should work as expected without any changes from your side.

savvan0h commented 1 month ago

Thanks for the quick fix! The issue is resolved now.