如何在此sqlalchemy查询中避免多个循环来获取我需要的排序?

时间:2012-08-14 03:35:18

标签: python sqlalchemy pyramid

我正在学习金字塔和sqlalchemy,并且正在努力解决如何在没有嵌套的foreach循环的情况下在数据库中执行查询的最佳方法。我相信有一种更有效的方式。

我有以下型号:

    class User(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        username = Column(Text)
        topicsfollowing = relationship('Topic', secondary=users_topics,
                                       backref='followers')

    class Article(Base):
        __tablename__ = 'articles'
        id = Column(Integer, primary_key=True)
        name = Column(Text)
        body = Column(Text)
        datepublished = Column(DateTime)
        focusid = Column(Integer, ForeignKey("topics.id"))
        focus = relationship("Topic", backref=backref('articles', order_by=id))

    class Topic(Base):
        __tablename__ = 'topics'
        id = Column(Integer, primary_key=True)
        name = Column(Text)

我还建立了用户和主题之间的M2M关系,如下所示:

    users_topics = Table('users_topics', Base.metadata,
                  Column('userid', Integer, ForeignKey('users.id')),
                  Column('topicid', Integer, ForeignKey('topics.id')))

基本上,我的用户可以关注主题,并且有关于每个主题(重点)的文章。我想弄清楚的是一个有效的方法来获取从用户遵循的所有主题的集合中编写的10篇最新文章的列表。例如,一个特定主题可以提供最近的所有10个,或者可能有10个主题,每个主题提供一篇最近的文章。

我能想到的唯一方法就是:

    user = DBSession.query(User).filter_by(id=logged_in).first()
    for topic in user.topicsfollowing:
        for article in topic.articles:
            # from here assemble a list of all articles from all followed
            # topics and then sort them descending by datepublished and take 
            # the first 10 in the list

但我知道必须有一种更有效的方法来做到这一点。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

您只需要执行一个查询即可获取用户所关注的主题ID列表,然后执行以下操作:

query(Article).filter(Article.focusid.in_(topic_ids)).order_by(desc(Article.datepublished)).limit(10)

我正在或多或少地写出我的头脑,所以我不确定它是否100%正确,但请参阅docs中的“IN”运算符。