0

I have been trying to get fastAPI to return recursive family tree without any success.

class DBPerson(Base):
    __tablename__ = 'person'

    id = Column(Integer, primary_key=True)
    name = Column(String, index=True)
    ...

    father_id = Column(Integer, ForeignKey("person.id"), nullable=True)
    father = relationship("DBPerson", back_populates="children")
    mother_id = Column(Integer, ForeignKey("person.id"), nullable=True)
    mother = relationship("DBPerson", back_populates="children")

    children = relationship("DBPerson", back_populates=???)

And to create a family tree, I want both father and mother to return their father and mother...

class PersonBase(BaseModel):
    name: str
    id: int
    father: PersonBase | None = None
    mother: PersonBase | None = None


class PersonMinimal(PersonBase):
    class Config:
        orm_mode = True

Though doing it like this returns an error inside the PersonBase class with father and mother as the PersonBase class has not been defined yet.

I have seen examples of this where you have a "parent", but that does not tell me whether I have the mother or father, unless the object in the list would also return the gender... but I would rather do it this way if possible. Any help appreciated.

Also, if anyone knows a way to limit how many generations the recursive will go, that would also be appreciated.

I would be expecting the api to return the following:

{
    id: int
    name: str
    father: {
        id: int
        name: str
        father: { ... }
        mother: { ... }
    }
    mother: {
        id: int
        name: str
        father: { ... }
        mother: { ... }
    }
}

1 Answer 1

0

You can either enter the type annotation as a string:

class PersonBase(BaseModel):
    name: str
    id: int
    father: "PersonBase | None" = None
    mother: "PersonBase | None" = None

or use from __future__ import annotations:

from __future__ import annotations

class PersonBase(BaseModel):
    name: str
    id: int
    father: PersonBase | None = None
    mother: PersonBase | None = None

See the pydantic docs for more information.

A word of warning however: if you're using PersonBase as a FastAPI response model, since both mother and father are also PersonBase, they will trigger recursive database calls until you've fetched the entire family tree. This might potentially be a costly operation if the tree gets deep, especially since the number of database roundtrips will grow exponentially.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.