2015-04-07 141 views
1

我已經定義,像這樣一個模型:加入和SQL-鍊金術算

class Article(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    authors = db.relationship('Author', secondary=articles_authors, backref=db.backref('articles', lazy='dynamic')) 
    tags = db.relationship('Tag', secondary=articles_tags, backref=db.backref('articles', lazy='dynamic')) 
    comments = db.relationship('Comment', backref=db.backref('article'), lazy='dynamic') 
    creation_time = db.Column(db.DateTime, default=datetime.datetime.utcnow) 
    modification_time = db.Column(db.DateTime, default=datetime.datetime.utcnow) 
    title = db.Column(db.String(256), nullable=False) 
    contents = db.Column(db.Text, nullable=False) 

我想創建一個查詢,會給我的所有文章加入了與作者和標籤,並且將計算相關評論給定的文章。這就是我想通了,至今:

Article.query.options(db.joinedload(Article.authors), db.joinedload(Article.tags)).all() 

是什麼給了我麻煩的是計數部 - 我無法找到如何做到這一點的任何例子。那我該怎麼做呢?

編輯:

查詢不工作,但感覺就像正確的方向:

subquery = db.session.query(Comment.article_id, func.count(Comment.id).label('comments_count'))\ 
      .group_by(Comment.article_id).subquery() 

return db.session.query(Article, subquery.c.comments_count)\ 
    .outerjoin(subquery, Article.id == subquery.c.article_id)\ 
    .join(Tag).all() 

在這種情況下,計數部工作正常,但使用我沒有收到標籤和作者這個查詢。

EDIT2:

如果不是很明顯 - 文章和標籤之間的關係是多到很多:

articles_tags = db.Table('articles_tags', 
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')), 
    db.Column('article_id', db.Integer, db.ForeignKey('article.id')) 
) 

也是一樣的文章和作者。

編輯:

答案:

subquery = db.session.query(Comment.article_id, func.count(Comment.id).label('comments_count'))\ 
      .group_by(Comment.article_id).subquery() 

return db.session.query(Article, subquery.c.comments_count)\ 
    .outerjoin(subquery, Article.id == subquery.c.article_id)\ 
    .options(db.joinedload(Article.authors), db.joinedload(Article.tags)).all() 
+0

爲什麼你使用'joinedload',而不是'join'?你想要計算什麼? – adarsh

+0

關於'joinedload' vs'join' - 不認識男人:)。我剛開始學習flask + sqlalchemy,我發現它很混亂。我想抽出關於文章的信息 - 誰寫了文章,分配了什麼標籤,文章有多少評論。 –

回答

3

我想你在找什麼可能是這樣的

(
    session.query(Article, func.count(Comment.id)) 
    .select_from(Comment) 
    .join(Comment.article) 
    .group_by(Article) 
) 

要獲得作者和標籤你應該(?)能夠僅在Article對象上使用.authors.tags。爲了加載它,你可以使用joinedload或subqueryload。

編輯:

(
    session.query(Article, func.count(Comment.id)) 
    .select_from(Comment) 
    .join(Comment.article) 
    .options(db.joinedload(Article.authors), db.joinedload(Article.tags)) 
    .group_by(Article) 
) 
+0

你能看看我更新的問題嗎? –

+0

您可以嘗試使用我的查詢在返回的「Article」對象上使用'.authors'或'.tags'嗎?每個人都必須是內部的子查詢,因爲它不是一個扁平的結構,因爲它很多很多 – adarsh

+0

雖然你的回答對我來說並不完全合適,但它促使我走上了一條良好的軌道,所以我接受了它。謝謝! –