How to print a model instance including a joined attribute? #1122
First Check
Commit to Help
Example Codeclass Product(SQLModel, table=True):
id: str = Field(primary_key=True)
ean: str
slug: str
brand: Optional[str]
name: str
price: float
category_id: int = Field(foreign_key="category.id")
description: Optional[str]
origin: Optional[str]
packaging: Optional[str]
unit_name: Optional[str]
unit_size: Optional[float]
is_variable_weight: bool = False
is_pack: bool = False
images: List["ProductImage"] = Relationship(back_populates="product")
price_history: List["PriceHistory"] = Relationship(back_populates="product")
nutritional_information: Optional["NutritionalInformation"] = Relationship(
back_populates="product"
)
class NutritionalInformation(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
product_id: str = Field(foreign_key="product.id")
calories: Optional[float]
total_fat: Optional[float]
saturated_fat: Optional[float]
polyunsaturated_fat: Optional[float]
monounsaturated_fat: Optional[float]
trans_fat: Optional[float]
total_carbohydrate: Optional[float]
dietary_fiber: Optional[float]
total_sugars: Optional[float]
protein: Optional[float]
salt: Optional[float]
product: Product = Relationship(back_populates="nutritional_information")
# ...
@api_router.get("/products/{product_id}")
def get_product(product_id: str, session: Session = Depends(get_session)):
result = session.exec(
select(Product, NutritionalInformation)
.join(NutritionalInformation)
.where(Product.id == product_id)
).first()
if result is None:
raise HTTPException(status_code=404, detail="Product not found")
product, nutritional_info = result
return {
**product.dict(),
"nutritional_information": nutritional_info.dict()
}DescriptionWhat's a better way of doing this? Operating SystemLinux Operating System DetailsNo response SQLModel Version0.0.22 Python Version3.11 Additional ContextNo response |
Answered by
YuriiMotov
Aug 20, 2025
Replies: 1 comment
|
You need to create "public" model that reflects db model, but redefines relationship fields (that you want to expose) as follows (use inheritance to reduce code duplication): class ProductBase(SQLModel):
id: str = Field(primary_key=True)
ean: str
slug: str
brand: Optional[str]
name: str
price: float
category_id: int = Field(foreign_key="category.id")
description: Optional[str]
origin: Optional[str]
packaging: Optional[str]
unit_name: Optional[str]
unit_size: Optional[float]
is_variable_weight: bool = False
is_pack: bool = False
class Product(ProductBase, table=True):
images: List["ProductImage"] = Relationship(back_populates="product")
price_history: List["PriceHistory"] = Relationship(back_populates="product")
nutritional_information: Optional["NutritionalInformation"] = Relationship(
back_populates="product"
)
class ProductPublic(ProductBase):
nutritional_information: Optional["NutritionalInformationPublic"] = NoneAnd then validate data using this "public" model: return ProductPublic.model_validate(product)Or use this model as response model and just return product. You can also use result = session.get(
Product,
product_id,
options=[
selectinload(Product.nutritional_information),
],
)Final endpoint (I didn't run this code): @api_router.get("/products/{product_id}")
def get_product(product_id: str, session: Session = Depends(get_session)) -> ProductPublic:
result = session.get(
Product,
product_id,
options=[
selectinload(Product.nutritional_information),
],
)
if result is None:
raise HTTPException(status_code=404, detail="Product not found")
return result |
0 replies
Answer selected by
YuriiMotov
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You need to create "public" model that reflects db model, but redefines relationship fields (that you want to expose) as follows (use inheritance to reduce code duplication):