2017-01-12 1 views
0

Предположим, что у меня есть следующие три класса, описывающие музыкальную коллекцию:Фильтр по многим-многим из родителей с SQLAlchemy

from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint 
from sqlalchemy import Table 
from sqlalchemy.orm import relationship 
from sqlalchemy.ext.declarative import declarative_base 


TRACK_NAME_LEN = 64 
ALBUM_NAME_LEN = 64 
TAG_NAME_LEN = 64 
URL_LEN = 255 


Base = declarative_base() 


class Track(Base): 

    __tablename__ = 'tracks' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(TRACK_NAME_LEN), nullable=False) 

    # many -> one 
    album_id = Column(Integer, ForeignKey('albums.id'), nullable=True) 
    album = relationship('Album', back_populates='tracks') 


# Auxiliary table for many <--> many relationship  
album_tag = Table('album_tag', Base.metadata, 
     Column('album_id', Integer, ForeignKey('albums.id')), 
     Column('tag_id', Integer, ForeignKey('tags.id'))) 


class Album(Base): 

    __tablename__ = 'albums' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(ALBUM_NAME_LEN), nullable=False) 

    # one -> many 
    tracks = relationship('Track', back_populates='album') 

    # many -> many 
    tags = relationship(
      'Tag', 
      secondary=album_tag, 
      back_populates='albums') 


class Tag(Base): 

    __tablename__ = 'tags' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(TAG_NAME_LEN), nullable=False, unique=True) 

    # many -> many 
    albums = relationship(
      'Album', 
      secondary=album_tag, 
      back_populates='tags') 

Альбом может иметь много различных меток. Мне нужен запрос, возвращающий все треки, чей альбом имеет данный тег. Вот что-то, что не работает:

rock = session.query(Tag).filter(name='rock').one() 
session.query(Track).join(Album).filter(Album.tags.any(rock)) 

Есть любое количество других неудачных попыток. Как мы это достигаем?

ответ

0

Это работает:

session.query(Track).filter(Track.album.has(Album.tags.any(name='tango'))).all() 
Смежные вопросы