SQLAlchemy:跨多对多关系的简单排序

时间:2018-04-05 16:01:22

标签: python sqlalchemy

我对SQLAlchemy很陌生,并试图弄清楚如何在与关联对象的多对多关系中设置最简单的order_by。我在这里看到了一些关于按计数排序的问题,但这不是更基本的问题。

假设这些表格(简化为实际表格):

class Event(db.Model):
    __tablename__ = 'event'
    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(255))
    date = db.Column(db.Date)

    guests = db.relationship('Guest_Event', back_populates='event')

class Guest(db.Model):
    __tablename__ = 'guest'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(256))

    events = db.relationship('Guest_Event', back_populates='guest')

class Guest_Event(db.Model):
    __tablename__ = 'guest_event'
    id = db.Column('id', db.Integer, primary_key=True)
    guest_id = db.Column('guest_id', db.Integer, db.ForeignKey('guest.id'))
    event_id = db.Column('event_id', db.Integer, db.ForeignKey('event.id'))
    guest = db.relationship('Guest', back_populates='events')
    event = db.relationship('Event', back_populates='guests')

我想做的就是拥有类似的东西:

event = Event.query.get(id)
# Then in a Jinja2 template:
<p>The following people were at this event:</p>
{% for guest_event in event.guests %}
  {{ guest_event.guest.name }} <br/>
{% endfor %}

此列表按guest.name排序,或类似地

guest = Guest.query.get(id)
# Jinja2:
<p>{{ guest.name }} was at these events:</p>
{% for guest_event in guest.events %}
    {{ guest_event.event.date }}: {{ guest_event.event.description }}<br/>
{% endfor %}

这是由event.date排序的,可能是降序。

我已经尝试将order_by='Guest.name'放入Guest_Event类或Event类中,这两个类都会在订单子句&#34;中抛出SQL错误&#34;未知列guest.name,这不足为奇此查询仅在关联表上运行。但我不知道还能做些什么。

最终,我想建立一个关联代理,因为我希望能够直接执行for guest in event.guests然后guest.name,而不是打扰关联类

另外:您如何动态更改此查询?例如,如果我想通过event.date在一种情况下升序,在另一种情况下降序,或在我在此简化示例中未显示的其他事件来订购事件。

1 个答案:

答案 0 :(得分:1)

或者:

1)构建新查询

guests = Guest.query.\
    join(Guest_Event).\
    join(Event).\
    filter(Event.id == event.id).\
    order_by(asc(Guest.name))

并循环显示这些结果,或

2)使用Python进行排序:

 for guest_event in sorted(event.guests, key=lambda x: x.name):