了解 SQLAlchemy ForeignKey 关系查询结果

Posted

技术标签:

【中文标题】了解 SQLAlchemy ForeignKey 关系查询结果【英文标题】:Understanding SQLAlchemy ForeignKey Relationship query results 【发布时间】:2020-11-22 01:59:27 【问题描述】:

我试图了解 SQLAlchemy 查询输出如何像无限对象一样连续嵌套。 (我确定这不是正确的称呼方式)

场景如下。 我在用户和他们的宠物之间创建了一对多的关系。

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")

现在,当我查询用户时,我还可以查询宠物信息,如下所示:

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

这会返回一个用户列表,其中包含他们的宠物在假想场中。 现在,当我尝试访问宠物信息时,我可以通过访问数组来实现。例如:

records[0].pets[0].name

同时我可以不断地再次访问用户,然后再次访问宠物数量和用户等等...

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

这个问题是我在探索graphQL的时候提出的,遇到了类似的情况。

我的问题是,这种现象是如何在 Python 中实现的?这是一个无限的对象还是有一些对象循环引用的东西? 很抱歉,我无法正确表述这一点,因为我不确定这个问题/功能叫什么。

非常感谢大家的宝贵时间,祝您有愉快的一天。

问候, 贾斯汀

编辑: 找到解释这一点的文档!https://docs.sqlalchemy.org/en/13/orm/self_referential.html

【问题讨论】:

如果你从前门离开房子,然后从后门进去,再从前门出去等等,房子会变得无限吗? 【参考方案1】:

我可以看到有问题的查询可能看起来是某种无限的对象链,但正如您自己指出的那样,这也许最好理解为循环引用的一种形式。

更具体地说,每个宠物对象都可以有一个所有者。反过来,每个主人可以拥有多只宠物。查询什么

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

你正在做的是你得到第一个宠物的主人,然后是那个主人的宠物,然后是第一个宠物的主人,等等。

因此我们也可以建立以下递归关系。

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

因此,在引擎盖下,无限链并不是真正的无限;查询只是绕圈子。 @Klaus D. 已经提供了一个很好的前门类比。我可能会在此处添加 CS 中另一个可能直观的参考,它是一种树数据结构:您正在从一个叶子移动到它的父节点,然后再返回到叶子。

【讨论】:

以上是关于了解 SQLAlchemy ForeignKey 关系查询结果的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy ForeignKey找不到表

SQLAlchemy 关系:与两个 ForeignKey 列中的任一个匹配的对象列表

SQLAlchemy学习-4.一对一关系

SQLAlchemy学习-4.一对一关系

SQLAlchemy Core中的异常及事务处理样码

Flask SQLAlchemy查询:从自己的外键关系中过滤记录