2012-11-22 21 views
12

Tôi đã yêu cầu cho một vấn đề tôi đã có trong SQLAlchemy và tìm thấy giải pháp trong khi viết. Tôi chỉ đăng nó trong trường hợp nó giúp ai đó :)SQLAlchemy làm thế nào để lọc theo trẻ em trong nhiều đến nhiều

Giả sử tôi có nhiều mối quan hệ dường như hoạt động (ít nhất tôi có thể tìm nạp trẻ em) Ba bảng: bài đăng, thẻ và post_tags.

import sqlalchemy as alc 

class Tag(Base): 
    __tablename__ = 'tags' 

    id = alc.Column(alc.Integer, primary_key=True) 
    name = alc.Column(alc.String) 
    accepted = alc.Column(alc.Integer) 

    posts = relationship('Post', secondary=post_tags) 



class Post(Base): 

    __tablename__ = 'posts' 

    id = alc.Column(alc.Integer, primary_key=True) 
    text = alc.Column(alc.String) 
    date_out = alc.Column(alc.Date) 

    tags = relationship('Mistake_Code', secondary=post_tags) 

# relational table 
post_tags = alc.Table('check_point_mistakes', 
         Base.metadata, 
         alc.Column('post_id', alc.Integer,ForeignKey('posts.id')), 
         alc.Column('tag_id', alc.Integer, alc.ForeignKey('tags.id'))) 

Bây giờ vấn đề của tôi là tôi muốn lọc đầu tiên bằng date_out trong bài đăng. Tôi có thể làm như sau:

# assume start_date and end_date 

query = (
      session.query(Post) 
        .filter(Post.date_out.between(start_date, end_date)) 
) 

Nhưng cách lọc theo thẻ cùng lúc?

Trả lời

16
query = (
    session.query(Post) 
      .join(Post.tags)  # It's necessary to join the "children" of Post 
      .filter(Post.date_out.between(start_date, end_date)) 
      # here comes the magic: 
      # you can filter with Tag, even though it was not directly joined) 
      .filter(Tag.accepted == 1) 
) 

Tuyên bố miễn trừ trách nhiệm: đây là ví dụ về giảm bớt veeery về mã thực của tôi, có thể tôi đã nhầm lẫn khi đơn giản hóa.

Tôi hy vọng nó sẽ giúp ai đó.