fastapi-cache icon indicating copy to clipboard operation
fastapi-cache copied to clipboard

Serialize to type hinted response type first?

Open PaleNeutron opened this issue 1 year ago • 1 comments

See here:

https://sqlmodel.tiangolo.com/tutorial/fastapi/relationships/#models-with-relationships

My example code

class StrategyWithPortfolios(StrategyWithCategory):

    portfolios: list[Portfolio] = []

@router.get("/all")
@cache(expire=60)
async def read_strategies(
    session: Session = Depends(get_session),
) -> list[StrategyWithPortfolios]:
    """
    get all Strategy
    """
    stmt = (
        session.query(Strategy)
        .options(
            joinedload(Strategy.portfolios).options(joinedload(Portfolio.investors))
        )
        .options(joinedload(Strategy.category).load_only(Category.name))
    )
    ret = stmt.all()
    ret = [StrategyWithPortfolios.model_validate(r) for r in ret]  # very important!!!!!
    return ret

The returned result is sqlalchemy orm class Strategy but the data structure I want to return is StrategyWithPortfolios.

The code works well without the line ret = [StrategyWithPortfolios.model_validate(r) for r in ret] and @cache(expire=60).

But if I add @cache(expire=60) it save fields only belong to Strategy not portfolios nor Category to redis.

Please serialize the returned result to given pydantic model before save it to backend.

PaleNeutron avatar Apr 08 '24 03:04 PaleNeutron

Late to the party, but if you add:

@router.get("/all", response_model=list[StrategyWithPortfolios])

In addition to keep the result annotation (->list[StrategyWithPortfolios]:) it seems to work. Also needed for the openapi.json to report the correct result type (instead of juststr).

Tested on FastAPI version 0.115.0.

Would be super nice if the worked without having to specify response model twise.

Just found that this is reported here as well #384

josteinl avatar Sep 18 '24 12:09 josteinl