按“关系”中定义的链接订购结果

时间:2013-10-26 07:48:13

标签: python sqlalchemy

我有表,我想做一个基于ORM的查询。

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    is_active = Column(Boolean, server_default="1", nullable=False)
    is_deleted = Column(Boolean, server_default="0", nullable=False)
    created_at = Column(DateTime, nullable = False, default=func.now())
    first_name = Column(String(30), nullable=False)
    surname_name = Column(String(30), nullable=False)

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    is_active = Column(Boolean, server_default="1", nullable=False)
    is_deleted = Column(Boolean, server_default="0", nullable=False)
    created_at = Column(DateTime, nullable = False, default=func.now())
    first_name = Column(String(30), nullable=False)
    surname_name = Column(String(30), nullable=False)
    appointments = relationship("ChildAppointment", backref="child")

class ParentChild(Base):
    '''provides a many to many relationship for parent and child'''
    __tablename__ = 'parent_child'
    id = Column(Integer, primary_key=True)
    is_active = Column(Boolean, nullable=False, server_default="1")
    is_deleted = Column(Boolean, nullable=False, server_default="0")
    parent_id = Column(Integer, ForeignKey('parent.id'), nullable=False)
    child_id = Column(Integer, ForeignKey('child.id'))

    parents = relationship("Parent", backref="parent_child")
    children = relationship("Child", backref="parent_child")

class ChildAppointment(Base):
    __tablename__ = 'child_appointment'
    id = Column(Integer, primary_key=True)
    is_active = Column(Boolean, nullable=False, server_default="1")
    is_deleted = Column(Boolean, nullable=False, server_default="0")
    created_at = Column(DateTime, nullable = False, default=func.now())
    child_id = Column(Integer, ForeignKey('child.id'))
    date_appointment = Column(DateTime, nullable = False)

我想查询表ParentChild并通过SQLAlchemy关系魔术,我想获得子的最新约会日期,这意味着我需要在子表中按date_appointment排序的结果。

我跟随@zeek here的例子,我想出了以下内容:

for data in session.query(ParentChild).join(Child.appointments).filter(ParentChild.parent_id == 1).\
        order_by(Child.appointments.date_appointment.desc()).all():

但是,我收到错误attributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Child.appointments has an attribute 'date_appointment'

我的场景打破了那个链接中给出的内容,因为我有4张桌子,因此我会额外填写表格,所以我无法调整他的答案以适应我的。

感谢。

1 个答案:

答案 0 :(得分:1)

两件事:首先,对于连接条件,您可能希望将其指定为一种链:

  • ParentChild - >子
  • 儿童 - > ChildAppointment

这样做是这样的:

session.query(ParentChild).join(ParentChild.children).join(Child.appointments)

这将产生正确的连接。我认为,如果它是明确的,你也可以这样做:

session.query(ParentChild).join(Child).join(ChildAppointment)

但是你必须尝试一下。

然而,真正的错误来自这一部分:

Child.appointments.date_appointment

相反它应该是这样的:

ChildAppointment.date_appointment

SQLAlchemy已经知道如何将此ChildAppointmentChildParentChild相关联,因为您在上面的join中指定了它。如果你用原始SQL术语来思考它,就会更有意义。

所以你最终解决方案:

session.query(ParentChild).join(ParentChild.children).join(Child.appointments).filter(ParentChild.parent_id == 1).order_by(ChildAppointment.date_appointment.desc()).all():