SQLAlchemy多对一加入

时间:2014-08-13 18:50:24

标签: python mysql sqlalchemy

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

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对象添加了相应的parent.child对象,但它只返回每个子项的第一个父项,即我的数据库中有四个父项和两个子项并且此查询仅返回父项1和3.如何修复查询以返回所有四个父项?我的第二个问题是,如果我想将孩子的名字添加到父母,而不是整个子对象,parent.child_name我将如何做到这一点?

1 个答案:

答案 0 :(得分:0)

如何在加入孩子时让所有父母

问题是有些父母没有孩子,所以使用普通加入会排除他们。请改用外连接。此外,只添加一个连接将不会实际加载孩子。您应指定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添加到父

您想使用association proxy

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

您可以使用关联代理执行一些很酷的操作,请务必阅读文档以获取更多信息。