2010-09-10 151 views
1

度日eagerload_all()在一定時間內的孩子我有一個表帖子它存儲3種後,主題回覆評論。每個人都有其父母ID。如何設置過濾器在SQLAlchemy的

# Single table inheritance 
class Post(Base): 
    __tablename__ = 'posts' 
    id = Column(Integer, primary_key=True) 
    parent_id = Column(Integer, ForeignKey('posts.id')) 
    discriminator = Column(String(1)) 
    content = Column(UnicodeText) 
    added_at = Column(DateTime) 
    __mapper_args__ = {'polymorphic_on': discriminator} 

class Topic(Post): 
    replies = relation("Reply") 
    __mapper_args__ = {'polymorphic_identity': 't'} 

class Reply(Post): 
    comments = relation("Comment") 
    __mapper_args__ = {'polymorphic_identity': 'r'} 

class Comment(Post): 
    __mapper_args__ = {'polymorphic_identity': 'c'} 

而且我使用eagerload_all()來獲取所有的答覆和意見屬於一個話題:

session.query(Topic).options(eagerload_all('replies.comments')).get(topic_id) 

我的問題是,如果我想只得到答覆和這些答覆的意見在某個時間段內,例如,本週或本月。我應該如何使用過濾器來實現這一目標?

謝謝

回答

1

採用eagerload_all只會查詢對象Topicchildren立即,而在第一次請求Replies和/或Comments,但因爲你的Topic對象加載到會話,其所有相關的孩子也會被加載。這給了你第一個選項:

選項1:在Python代碼,而不是database篩選:
基本上創建一個類似於

class Topic(Post): 
    ... 
    def filter_replies(self, from_date, to_date): 
     return [r for r in self.replies 
       if r.added_at >= from_date 
       and r.added_at <= to_date] 

Topic對象的一個​​方法。然後,你可以做類似Replies上的代碼來過濾Comments或這些的任意組合。你明白了。

選項2:在database級過濾:
爲了實現這一點,你不需要加載Topic對象,而是直接在Reply/Comment過濾。下面的查詢返回所有Reply對於給定Topic帶有日期過濾器:

topic_id = 1 
from_date = date(2010, 9, 5) 
to_date = date(2010, 9, 15) 
q = session.query(Reply) 
q = q.filter(Reply.parent_id == topic_id) 
q = q.filter(Reply.added_at >= from_date) 
q = q.filter(Reply.added_at <= to_date) 
for r in q.all(): 
    print "Reply: ", r 

版本的註釋,你才能克服SQL語句產生問題,因爲需要一個別名是隻是一點點更多地參與所有的對象映射到同一個表名:

topic_id = 1 
from_date = date(2010, 9, 5) 
to_date = date(2010, 9, 15) 
ralias = aliased(Reply) 
q = session.query(Comment) 
q = q.join((ralias, Comment.parent_id == ralias.id)) 
q = q.filter(ralias.parent_id == topic_id) 
q = q.filter(Comment.added_at >= from_date) 
q = q.filter(Comment.added_at <= to_date) 
for c in q: 
    print "Comment: ", c 

很明顯,你可以創建一個既能撕成小塊組合成一個更全面的查詢功能。
爲了實現this weekthis month查詢類型,您可以將這些過濾器轉換爲如上所示的日期範圍或使用SA的expression.func功能。