Can I sort nested connections as part of a query using ORM rather than a separate for loop? #1102
-
First Check
Commit to Help
Example CodeI have a basic one to many relationship. The models look something like this: class Track(TrackBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
# ...
sort_order: int
release_id: uuid.UUID | None = Field(default=None, foreign_key="release.id")
release: Release | None = Relationship(back_populates="tracks")
class Release(ReleaseBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
# ...
tracks: list["Track"] = Relationship(back_populates="release") And my endpoint looks like this: @router.get("/", response_model=ReleasesOut)
def read_releases(session: SessionDep, skip: int = 0, limit: int = 100) -> Any:
"""
Retrieve releases.
"""
count_statement = select(func.count()).select_from(Release)
count = session.exec(count_statement).one()
statement = select(Release).offset(skip).limit(limit)
releases = session.exec(statement).all()
for release in releases:
if release.tracks:
release.tracks.sort(key=lambda track: track.sort_order)
releases_public = list(map(release_public_to_release_out, releases))
return ReleasesOut(data=releases_public, count=count) In this example I'm sorting the tracks after the query is executed. This works but there are some issues:
|
Beta Was this translation helpful? Give feedback.
Answered by
YuriiMotov
Aug 20, 2025
Replies: 1 comment
-
You can specify the sort order for relationship field:
Runnable code example in the details: from typing import Optional, List
from sqlmodel import SQLModel, Field, Relationship, create_engine, Session, select
class Team(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
headquarters: str
heroes: List["Hero"] = Relationship(back_populates="team", sa_relationship_kwargs={"order_by": "Hero.name"})
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
team: Optional[Team] = Relationship(back_populates="heroes")
# --- Setup database ---
engine = create_engine("sqlite:///", echo=False)
SQLModel.metadata.create_all(engine)
# --- Example usage ---
with Session(engine) as session:
# Create a team
avengers = Team(name="Avengers", headquarters="New York")
session.add(avengers)
session.commit()
session.refresh(avengers)
# Create heroes and link them to the team
ironman = Hero(name="Iron Man", secret_name="Tony Stark", age=45, team=avengers)
hulk = Hero(name="Hulk", secret_name="Bruce Banner", age=40, team=avengers)
superman = Hero(name="Superman", secret_name="???", age=30, team=avengers)
session.add_all([ironman, hulk, superman])
session.commit()
# Query with relationship
statement = select(Team).where(Team.name == "Avengers")
result = session.exec(statement).one()
print("Heroes:", [hero.name for hero in result.heroes]) Output:
|
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 can specify the sort order for relationship field:
Runnable code example in the details: