2014-12-23 33 views
0

我工作的SQLAlchemy 0.9.8如何渴望負載可選地存在過濾關係

這個問題是有關「How to filter by joinloaded table in SqlAlchemy?」,但不一樣的。

我有Article實體,它的可選本地化由ArticleL10n實體。

Base = declarative_base() 

class Article(Base): 
    __tablename__ = 'article' 
    id = Column(Integer, primary_key=True) 
    title = Column(String(255)) 
    l10n = relationship("ArticleL10n", 
      collection_class=attribute_mapped_collection('lang'), 
      cascade="all, delete-orphan") 

class ArticleL10n(Base): 
    __tablename__ = 'article_10n' 
    article_id = Column(Integer, ForeignKey('article.id'), primary_key=True) 
    lang = Column(String(15), primary_key=True) 
    title = Column(String(255)) 

我想查詢Article列表與特定語言的預先加載ArticleL10n

我已經試過:

session.query(Article) \ 
    .outerjoin(Article.l10n) \ 
    .options(contains_eager(Article.l10n)) \ 
    .filter(ArticleL10n.lang == "en") \ 
    .all() 

這是不行的,因爲如果文章沒有"en"本地化,它會被過濾掉。

我當前工作的代碼是這樣的:

session.query(Article) \ 
    .outerjoin(ArticleL10n, and_(ArticleL10n.article_id == Article.id, ArticleL10n.lang == "en")) \ 
    .options(contains_eager(Article.l10n)) \ 
    .all() 

這似乎是工作。但我不喜歡這個,因爲ArticleL10n.article_id == Article.id部分看起來像是多餘的。我相信應該有更好的方法來做到這一點。

我該如何簡化?

+1

我認爲您的解決方案是一個很好的,和連接部分是絕對不能*多餘*。你可以通過使用關係來使它變得更清潔:'.outerjoin(ArticleL10n,and_(Article.l10n,ArticleL10n.lang ==「en」))' – van

+0

@van謝謝,我不知道我們可以使用在'and_'子句中''關係'。我認爲這正是我所尋找的。請寫一個答案,以便我可以標記它是正確的。 – rintaro

+0

我也不知道,但鑑於這個問題非常合理,我認爲邁克已經遇到了這個問題。 – van

回答

0

您可以使用relationship,而不是直接在連接條件的爲您join的第一部分:

.outerjoin(ArticleL10n, and_(Article.l10n, ArticleL10n.lang == "en"))