I have tree structure in database - comments.
class Comment(SQLModel, table=True):
id: int = Field(primary_key=True, nullable=False, unique=True)
text: str = Field(nullable=False)
parent_id: int = Field(nullable=True, foreign_key="comment.id")
parent: Optional["Comment"] = Relationship(back_populates="children")
children: Optional[List["Comment"]] = Relationship(
back_populates="parent", sa_relationship_kwargs={
"lazy": "joined", "join_depth": 100, "remote_side": "Comment.id"
}
)
class CommentSchema(BaseModel):
id: int
text: str
children: Optional["CommentSchema"] = None
# children: Optional[List["CommentSchema"]] = []
Commented code returns error:
'msg': "Error iterating over object, error: AttributeError: 'Comment' object has no attribute 'pydantic_extra'",
Uncommented code return list:
[
{
"id": 2 (child id 2),
"children": {
"id": 1 (parent id 1),
}
},
{
"id": 6 (subchild id 6),
"children": {
"id": 2 (child id 2),
"children": {
"id": 1(parent id 1),
}
}
},
{
"id": 5,
"children": {
"id": 2 (child id 2),
"children": {
"id": 1 (parent id 1),
}
}
},
{
"id": 4 (subchild id 4),
"children": {
"id": 2 (child 2),
"children": {
"id": 1 (parent id 1),
}
}
},
{
"id": 3 (subchild id 3),
"children": {
"id": 2 (child id 2),
"children": {
"id": 1 (parent id 1),
}
}
},
{
"id": 1 (parent id 1),
}
]
I think it is absolutely clear why I'm not happy with the result. Is there any way to get correct tree structure from database except writting raw sql queries?
First of all:
schemas.py
class CommentSchema(BaseModel):
id: int
text: str
children: Optional[List["CommentSchema"]] = []
models.py:
class Comment(SQLModel, table=True):
id: int = Field(primary_key=True, nullable=False, unique=True)
text: str = Field(nullable=False)
created: datetime = Field(sa_column=Column(DateTime(timezone=True), server_default=func.now()))
parent_id: int = Field(nullable=True, foreign_key="comment.id")
children: Optional[List["Comment"]] = Relationship(
sa_relationship_kwargs={
"lazy": "selectin",
"join_depth": 100,
"order_by": "Comment.created.desc()",
"cascade": "delete",
},
)
And it works