uriyyo / fastapi-pagination

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

TypeError: unhashable type: 'dict' when trying to use Sqlalchemy 2.0 syntax #922

Closed sahil-kumar-1129 closed 5 months ago

sahil-kumar-1129 commented 8 months ago

Hi team, I am currently using fastapi-pagination v0.11.4 and trying to upgrade my sqlalchemy queries to be 2.0 compliant which means converting Query objects to Select objects. This meant I needed to use the paginate function from ext.sqlalchmey_future.py instead of ext.sqlalchemy.py. The migration was going smooth until I need to paginate some queries on table with JSON columns. Then I started receiving the error TypeError: unhashable type: 'dict' trying to return that column by passing my Select query into paginate from ext.sqlalchmey_future.py. Is there a good work around for this issue/if I upgrade the package to a certain version, will it fix this issue and still allow me to continue with my upgrade of the sqlachemy quries?

uriyyo commented 8 months ago

Hi @sahil-kumar-1129,

Could you please try to use unique=False parameter?

sahil-kumar-1129 commented 8 months ago

There is no unique parameter. This is the function code:

def paginate( conn: Union[Connection, Engine, Session], query: Select, params: Optional[AbstractParams] = None, ) -> AbstractPage: params = resolve_params(params)

total = conn.scalar(select(func.count()).select_from(query.subquery()))
items = conn.execute(paginate_query(query, params))

return create_page(items.scalars().unique().all(), total, params)

We're using v0.11.4

uriyyo commented 8 months ago

You need to upgrade to latest fastapi-pagination version

jshields commented 8 months ago

I believe we got this working using unique=False with sqlalchemy_future as the paginator on 0.11.4. We are working towards an upgrade path to the latest version. Thank you!

Also noting distinct() is used with the SQLAlchemy select query.

uriyyo commented 8 months ago

Hi @sahil-kumar-1129,

If it's not possible to upgrade to newest version you can use this function:

from typing import Union, Optional, Any

from sqlalchemy import select, func
from sqlalchemy.orm import Session
from sqlalchemy.engine import Engine, Connection
from sqlalchemy.sql import Select

from fastapi_pagination import resolve_params, create_page
from fastapi_pagination.bases import AbstractParams
from fastapi_pagination.ext.sqlalchemy import paginate_query

def paginate(
    conn: Union[Connection, Engine, Session],
    query: Select,
    params: Optional[AbstractParams] = None,
    *,
    unique: bool = True,
) -> Any:
    params = resolve_params(params)

    total = conn.scalar(select(func.count()).select_from(query.subquery()))
    items = conn.execute(paginate_query(query, params))

    if unique:
        items = items.unique()

    return create_page(items.all(), total, params)
uriyyo commented 7 months ago

Any updates? Can I close this issue?

jshields commented 6 months ago

Using unique=False with sqlalchemy_future as the paginator on version 0.11.4, there is no issue. Thanks. This issue can be closed 👍