2012-11-22 15 views
12

Prosiłem o problem, który miałem w SQLAlchemy i znalazłem rozwiązanie podczas pisania. Mimo to publikuję go na wszelki wypadek, na wypadek gdyby pomógł komuś :)SQLAlchemy jak filtrować przez dzieci w wielu do wielu

Załóżmy, że mam wiele do wielu relacji, które wydają się działać (przynajmniej mogę sprowadzić dzieci) Trzy tabele: posty, tagi i post_tagi.

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'))) 

Teraz mój problem polega na tym, że chcę najpierw filtrować według date_out w poście. Mogę to zrobić tak:

# assume start_date and end_date 

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

Ale jak filtrować według tagów w tym samym czasie?

Odpowiedz

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) 
) 

Nota prawna: jest to ograniczający przykład mojego rzeczywistego kodu, mogłem popełnić błąd upraszczając.

Mam nadzieję, że to pomoże komuś.

Powiązane problemy