2017-01-12 3 views
0

Angenommen, ich habe die folgenden drei Klassen eine Musik-Sammlung zu beschreiben:Filter auf viele-viele-Beziehung von Eltern mit 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') 

Ein Album viele verschiedene Tags haben. Ich möchte eine Abfrage, die alle Titel zurückgibt, deren Album ein bestimmtes Tag hat. Hier ist etwas, das nicht funktioniert:

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

Es gibt eine beliebige Anzahl von anderen Fehlversuche. Wie erreichen wir das?

Antwort

0

Dies funktioniert:

session.query(Track).filter(Track.album.has(Album.tags.any(name='tango'))).all() 
Verwandte Themen