Python 使用sqlalchemy筛选父级的多个关系

Python 使用sqlalchemy筛选父级的多个关系,python,join,sqlalchemy,Python,Join,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_

假设我有以下三个类来描述一个音乐收藏:

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')
还有许多其他失败的尝试。 我们如何做到这一点?

这是可行的:

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