3

私はピラミッドと 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 件の記事のリストを取得する効率的な方法です。たとえば、1 つの特定のトピックが最新の 10 件すべてを提供する場合もあれば、10 のトピックがあり、それぞれが 1 つの最近の記事を提供する場合もあります。

私が考えることができる唯一の方法は、次のようなものです。

    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

しかし、これを行うにはもっと効率的な方法が必要であることはわかっています。どんな助けでも大歓迎です。

4

1 に答える 1

4

ユーザーがフォローしているトピック ID のリストを取得するために 1 つのクエリを実行するだけで、次のように実行できます。

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

多かれ少なかれ頭のてっぺんから書いているので、100%正しいかどうかはわかりませんが、docsの「IN」演算子を参照してください。

于 2012-08-14T04:02:01.963 に答える