Как запросить отношение многие ко многим в SQLAlchemy ORM? - PullRequest
0 голосов
/ 07 июля 2019

Мне известно, что этот вопрос уже задавался несколько раз, но ни один из результатов не помог.

У меня есть отношение многие ко многим между дорожками таблиц и жанрами, которое выглядит следующим образом:

track_genres = Table('track_genres',
                     Base.metadata,
                     Column('tracks_id', INTEGER, ForeignKey('tracks.id'), primary_key=True),
                     Column('genres_id', INTEGER, ForeignKey('genres.id'), primary_key=True)
                     )

class Genre(Base):
    __tablename__ = 'genres'
    id = Column(INTEGER, primary_key=True, unique=True, autoincrement=True, nullable=False)
    name = Column(TEXT)


class Track(Base):
    __tablename__ = 'tracks'
    id = Column(INTEGER, primary_key=True, unique=True, autoincrement=True, nullable=False)
    name = Column(TEXT)
    album_id = Column(INTEGER, ForeignKey('albums.id'))
    genres = orm.relationship('Genre', secondary=track_genres, backref=orm.backref('tracks', lazy='dynamic',cascade='all'))

Насколько мне известно, отношения объявлены правильно, поскольку у меня есть следующие отношения в таблице track_genres:

tracks_id | genres_id
---------------------
1         | 1        
1         | 2        
1         | 3        
1         | 4        
2         | 1        
2         | 2        
2         | 3        
2         | 4        
3         | 5        
3         | 6        
3         | 7        

Теперь проблема в том, что когда я выполняю свой текущий запрос

    query = session.query(
        Track,
        Genre.name.label('genre_name')
    ).filter(
        Track.genres.any(id=Genre.id)
    )

Я получаю результат, который включает все перестановки данных, поэтому трек с идентификатором 1 возвращается запросом 7 раз (один раз с каждым идентификатором жанра от 1 до 7), даже если он должен быть возвращен только 4 раз (поскольку для дорожки только 4 связи с идентификатором 1: 1-1, 1-2, 1-3, 1-4)

Как мне написать свой фильтр / объединение в запросе, чтобы запрос возвращал только правильные результаты (в данном случае для трека с ID = 1, четыре строки) вместо выполнения всех возможных перестановок?

1 Ответ

0 голосов
/ 07 июля 2019

После дальнейших экспериментов я считаю, что правильный подход - соединить соответствующие отношения из треков:

    query = session.query(
        Track,
        Genre.name.label('genre_name')
    ).join.(
        Track.genres
    )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...