SQLAlchemy多对一连接



我使用SQLAlchemy在两个SQL表之间有多对一的关系。例如:

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    child_id = Column(Integer, ForeignKey('child.id'))
    child = relationship("Child")
class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    name = Column(String(100))

我希望能够做的是能够将Child类的信息添加到父类。我尝试了join查询:

result = session.query(Parent).join(Child).all()

虽然这个查询将适当的Child对象添加到parent.childParent对象,但它只返回每个孩子的第一个父母,即我在数据库中有四个父母和两个孩子,这个查询只返回父母1和3。如何修复查询以返回所有四个父节点?第二个问题是,如果我只想将孩子的名字添加到父对象,而不是整个孩子对象,如parent.child_name,我该怎么做呢?

如何获取所有父节点加入到子节点

问题是有些父节点没有子节点,所以使用普通连接会将它们排除在外。请使用外连接。此外,仅仅添加一个连接实际上不会加载子节点。您应该指定contains_eagerjoinedload,以便与父元素一起加载子元素。

# use contains_eager when you are joining and filtering on the relationship already
session.query(Parent).join(Parent.child).filter(Child.name == 'Max').options(contains_eager(Parent.child))
# use joinedload when you do not need to join and filter, but still want to load the relationship
session.query(Parent).options(joinedload(Parent.child))

如何将child_name添加到父节点

您想使用关联代理。

from sqlalchemy.ext.associationproxy import association_proxy
class Parent(Base):
    child = relationship('Child')
    child_name = association_proxy('child', 'name')
# you can filter queries with proxies:
session.query(Parent).filter(Parent.child_name == 'Min')

使用关联代理可以做一些很酷的事情,请务必阅读文档以获取更多信息

最新更新