Grouped result of multiple joins #1512
-
First Check
Commit to Help
Example Codedef get_model_detail(session: Session, id: int):
data = session.query(ModelProfile, SubModelProfile).join(SubModelProfile, ModelProfile.id == SubModelProfile.mp_id).filter(ModelProfile.id == id).all()
return data Description
Question: I'm expecting the result to look like:
Or this (what I wish to achieve)
Operating SystemWindows Operating System DetailsNo response SQLModel Version0.0.4 Python Version3.7.11 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
This is an SQL question, not related to SQLModel. Here, you are selecting from both tables with a join on both tables:
Let us focus on Say you have 3 When you join the tables, the rows look like this:
However, since you have a condition that To avoid repetition, do not include SQLAlchemy should be able to infer how to join the two tables. It should be enough to use |
Beta Was this translation helpful? Give feedback.
-
@tiangolo any updates |
Beta Was this translation helpful? Give feedback.
-
You can specify relationships between these models: class ModelProfile(ModelProfileBase, table=True):
...
sub_model_profiles: list["SubModelProfile"] = Relationship(back_populates="model_profile")
class SubModelProfile(SQLModel, table=True):
...
mp_id: int = Field(foreign_key="modelprofile.id")
model_profile: ModelProfile = Relationship(back_populates="sub_model_profiles") And then fetch it just like this: mp1_db = session.get(ModelProfile, 1) or with mp1_db = session.exec(
select(ModelProfile)
.where(ModelProfile.id == 1)
.options(selectinload(ModelProfile.sub_model_profiles))
).one() Runnable code example in the details: from typing import Optional
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
from sqlalchemy.orm import selectinload
engine = create_engine("sqlite:///")
def create_db_and_tables():
SQLModel.metadata.drop_all(engine)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
mp1 = ModelProfile(
model_version="1", sub_model_profiles=[SubModelProfile(), SubModelProfile()]
)
mp2 = ModelProfile(
model_version="2", sub_model_profiles=[SubModelProfile(), SubModelProfile()]
)
session.add_all([mp1, mp2])
session.commit()
class ModelProfileBase(SQLModel):
model_version: str
class ModelProfile(ModelProfileBase, table=True):
id: Optional[int] = Field(primary_key=True, nullable=False)
sub_model_profiles: list["SubModelProfile"] = Relationship(
back_populates="model_profile"
)
class ModelProfileRead(ModelProfileBase):
id: int
sub_model_profiles: list["SubModelProfile"]
class SubModelProfile(SQLModel, table=True):
id: Optional[int] = Field(primary_key=True, nullable=False)
mp_id: int = Field(foreign_key="modelprofile.id")
model_profile: ModelProfile = Relationship(back_populates="sub_model_profiles")
def main():
create_db_and_tables()
with Session(engine) as session:
mp1_db = session.get(ModelProfile, 1)
# Or with select:
# ----------------
# mp1_db = session.exec(
# select(ModelProfile)
# .where(ModelProfile.id == 1)
# .options(selectinload(ModelProfile.sub_model_profiles))
# ).one()
# ----------------
print(mp1_db.sub_model_profiles)
print(ModelProfileRead.model_validate(mp1_db).model_dump())
if __name__ == "__main__":
main() |
Beta Was this translation helpful? Give feedback.
You can specify relationships between these models:
And then fetch it just like this:
or with
select
and eager loading:Runna…