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 |
Beta Was this translation helpful? Give feedback.
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"] = None And 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 |
Beta Was this translation helpful? Give feedback.
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):