简体   繁体   中英

Understanding SQLAlchemy ForeignKey Relationship query results

I'm trying to understand how SQLAlchemy query output can be continuously nested as if its an infinite object. (I sure this is not the right way to call it)

The scenario is as below. I have created a one-to-many relationship between a user and their pets.

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)

    pets = relationship("Pet", back_populates="owner")

class Pet(Base):
    __tablename__ = "pets"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    owner_id = Column(Integer, ForeignKey("users.id"))

    owner = relationship("User", back_populates="pets")

Now, when I query for the User, I could also query for the pets information as seen below:

records = session.query(User).all()

This returns a list of users with their pets in the imaginary field.
Now when I try to get access to the pets information, I can do so by accessing the array. For example:

records[0].pets[0].name

At the same time, I can continuously access the user again, and then the number of pets and the user again and so on...

records[0].pets[0].owner.pets[0].owner.pets[0].....

This question was raised when I was exploring graphQL and encountered something similar.

My question is, how is this phenomena made possible in Python? Is this an infinite object or is there some object circular referencing thing? I am sorry I could not put this in the right wording as I am unsure what is this problem/ feature called.

Thank you all very much for your time and have a pleasant day.

Regards,
Justin

EDIT:
Found the docs that explains this!
https://docs.sqlalchemy.org/en/13/orm/self_referential.html

I can see how the query in question may appear to be some sort of infinite chain of objects, but as you've pointed out yourself, this is perhaps best understood as a form of circular reference.

More concretely, each pet object can have one owner. In turn, each owner can have multiple pets. What the query

records[0].pets[0].owner.pets[0].owner.pets[0].....

is doing is that you're getting the owner of the first pet, then the pets of that owner, then the owner of the first pet, and so forth.

We can thus establish the following recurrence relationship as well.

records[0].pets[0] = records[0].pets[0].owner.pets[0]

So the infinite chain is, under the hood, not truly infinite; the query is simply going in circles. @Klaus D. has already provided an excellent analogy of a front door. I might add in here another potentially intuitive reference in CS, which is a tree data structure: you're moving from one leaf to its parent node, then back down to the leaf.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM