Replies: 1 comment
-
|
Hey @seklmco, thanks for the kind words! You're encountering a fundamental difference between how FastAPI response models work versus FastCRUD select schemas.
When you set To get this behavior, you have a few options: Option 1: Use custom endpoint with joins from fastcrud import FastCRUD, JoinConfig
from sqlalchemy.orm import selectinload
crud_library = FastCRUD(Library)
library_router = crud_router(
session=get_async_session,
model=Library,
path="/libraries",
tags=["Library"]
# No select_schema with relationships
)
# Override the get endpoint to handle relationships
@library_router.get("", response_model=list[LibraryRead])
async def get_libraries_with_books(db: AsyncSession = Depends(get_async_session)):
# Option A: Use FastCRUD's get_multi_joined
result = await crud_library.get_multi_joined(
db=db,
join_config=[JoinConfig(model=Book, join_type="left")],
schema_to_select=LibraryRead,
nest_joins=True
)
return result
# Option B: Use SQLAlchemy directly
# result = await db.exec(select(Library).options(selectinload(Library.books)))
# return result.all()Option 2: Separate the response schema from select schema class LibrarySelect(LibraryBase):
id: str
# No books field here - just what exists in the table
class LibraryRead(LibraryBase):
id: str
books: list[Book] # For response serialization
library_router = crud_router(
session=get_async_session,
model=Library,
path="/libraries",
tags=["Library"],
select_schema=LibrarySelect # Only selects table columns
)
# Override the get endpoint to load relationships
@library_router.get("", response_model=list[LibraryRead])
async def get_libraries_with_books(db: AsyncSession = Depends(get_async_session)):
result = await db.exec(select(Library).options(selectinload(Library.books)))
return result.all()Option 3: Skip select_schema entirely library_router = crud_router(
session=get_async_session,
model=Library,
path="/libraries",
tags=["Library"]
# No select_schema - FastCRUD selects all table columns
)
# Override to include relationships and set response model
@library_router.get("", response_model=list[LibraryRead])
async def get_libraries(db: AsyncSession = Depends(get_async_session)):
result = await db.exec(select(Library).options(selectinload(Library.books)))
return result.all()
IMO option 1 is the best out of the three, but this is an actual limitation we need to work on. I'll create an issue |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello. To start off, I have to admit this library is an amazing time saver so thank you for creating it.
I want to learn about how to define a custom response model at the router level (
crud_router). I see that there is theselect_schemaparameter. However, when I define it to be something likeLibraryRead, it is trying to read a relationship field from the database, which does not exists. Take a look at these models as an example (I'm usingsqlmodel):I would then want
LibraryReadto be the response model so FastAPI can automatically respond with the appropriate data. With FastAPI, I would define the endpoint like this and thebookslist would be included in the response:However, when I set the
select_schematoLibraryRead, it looks like it is attempting to readbooksfrom the database. Which I suppose makes sense but not the functionality I am looking for.If I don't set
select_schemathen the response, as expected, only includesidandnamefields.Let me know what I am missing. Thank you!
Beta Was this translation helpful? Give feedback.
All reactions