How can I query or order_by with Link Model with Extra Fields in a many-to-many relation? #819
-
First Check
Commit to Help
Example Codeclass UserRoomLink(SQLModel, table=True):
room_id: Optional[int] = Field(
default=None, foreign_key="room.id", primary_key=True
)
user_id: Optional[int] = Field(
default=None, foreign_key="user.id", primary_key=True
)
created_at: datetime = Field(
default_factory=datetime.utcnow, index=True, nullable=False
)
class Room(RoomBase, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
users: List["User"] = Relationship(back_populates="rooms", link_model=UserRoomLink)
class User(UserBase, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
rooms: Optional[Room] = Relationship(
back_populates="users", link_model=UserRoomLink
) DescriptionHow can I query or order_by with Link Model with Extra Fields? Operating SystemmacOS Operating System DetailsNo response SQLModel Version0.0.14 Python Version3.10.5 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I am experimenting with something akin to this:
But seems to be perfectly ignored on an object... (unless I need to re-query object or something like that). |
Beta Was this translation helpful? Give feedback.
-
You can specify rooms: List[Room] = Relationship(
back_populates="users",
link_model=UserRoomLink,
sa_relationship_kwargs={
"order_by": "UserRoomLink.created_at",
},
) Try changing Runable code example in the details: from datetime import datetime, timedelta
from typing import List, Optional
from sqlmodel import SQLModel, Field, Relationship, create_engine, Session
class UserRoomLink(SQLModel, table=True):
room_id: Optional[int] = Field(
default=None, foreign_key="room.id", primary_key=True
)
user_id: Optional[int] = Field(
default=None, foreign_key="user.id", primary_key=True
)
created_at: datetime = Field(
default_factory=datetime.utcnow, index=True, nullable=False
)
class Room(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
users: List["User"] = Relationship(back_populates="rooms", link_model=UserRoomLink)
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
rooms: List[Room] = Relationship(
back_populates="users", link_model=UserRoomLink, sa_relationship_kwargs={
"order_by": "UserRoomLink.created_at.desc()",
},
)
engine = create_engine("sqlite:///")
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
room1 = Room(name="Test Room")
room2 = Room(name="Test Room 2")
user = User()
session.add(room1)
session.add(room2)
session.add(user)
session.commit()
session.refresh(room1)
session.refresh(room2)
session.refresh(user)
link1 = UserRoomLink(room_id=room1.id, user_id=user.id, created_at=datetime.utcnow())
link2 = UserRoomLink(room_id=room2.id, user_id=user.id, created_at=datetime.utcnow() + timedelta(seconds=1))
session.add(link1)
session.add(link2)
session.commit()
user = session.get(User, 1)
assert len(user.rooms) == 2
assert user.rooms[0].name == "Test Room 2" # created_at is more recent
assert user.rooms[1].name == "Test Room" |
Beta Was this translation helpful? Give feedback.
You can specify
sa_relationship_kwargs={"order_by": "UserRoomLink.created_at.desc()"}
to your relationship attribute:Try changing
"order_by": "UserRoomLink.created_at"
to"order_by": "UserRoomLink.created_at.desc()"
and see that order will be different.Runable code example in the details: