Я несколько разветвленная структура отношения (позволяет использовать пример базы данных сватовства - фактический случай является немного более сложным, к сожалению):Разветвленные отношения с SQLAlchemy
class Hobby(Base):
__tablename__ = 'hobby'
id = Column(Integer, primary_key=True)
hobby_name = Column(String(255, u'utf8_unicode_ci'), nullable=False)
class Guy(Base):
__tablename__ = 'guy'
id = Column(Integer, primary_key=True)
name = Column(String(255, u'utf8_unicode_ci'), nullable=False)
class Girl(Base):
__tablename__ = 'girl'
id = Column(Integer, primary_key=True)
name = Column(String(255, u'utf8_unicode_ci'), nullable=False)
class Match(Base):
__tablename__ = 'match'
id = Column(Integer, primary_key=True)
guy_id = Column(ForeignKey(u'guy.id'), nullable=False)
girl_id = Column(ForeignKey(u'girl.id'), nullable=False)
guy = relationship(u'Guy', backref = 'matches')
girl = relationship(u'Girl', backref = 'matches')
class GuyHobbies(Base):
__tablename__ = 'guy_hobbies'
id = Column(Integer, primary_key=True)
guy_id = Column(ForeignKey(u'guy.id'), nullable=False)
hobby_id = Column(ForeignKey(u'hobby.id'), nullable=False)
guy = relationship(u'Guy', backref = 'hobbies')
hobby = relationship(u'Hobby', backref = 'guys')
class GirlHobbies(Base):
__tablename__ = 'girl_hobbies'
id = Column(Integer, primary_key=True)
girl_id = Column(ForeignKey(u'girl.id'), nullable=False)
hobby_id = Column(ForeignKey(u'hobby.id'), nullable=False)
girl = relationship(u'Girl', backref = 'hobbies')
hobby = relationship(u'Hobby', backref = 'girls')
Теперь я хочу, чтобы получить соединение между GirlHobby и GuyHobby, который учитывает оба отношения через Хобби и через Матч. I.e., я делаю
matched_hobbies = session.query(GuyHobbies).join(GuyHobbies.guy).\
join(GuyHobbies.hobby).join(Guy.matches).\
join(Match.girl).outerjoin(Girl.hobbies).all()
Однако сгенерированный запрос пропускает часть, указанную ниже. Как заставить SQLAlchemy добавить это условие?
SELECT guy_hobbies.id AS guy_hobbies_id, guy_hobbies.guy_id AS guy_hobbies_guy_id,
guy_hobbies.hobby_id AS guy_hobbies_hobby_id
FROM guy_hobbies INNER JOIN guy ON guy.id = guy_hobbies.guy_id
INNER JOIN hobby ON hobby.id = guy_hobbies.hobby_id
INNER JOIN `match` ON guy.id = `match`.guy_id
INNER JOIN girl ON girl.id = `match`.girl_id
LEFT OUTER JOIN girl_hobbies ON girl.id = girl_hobbies.girl_id
#MISSING: AND hobby.id = girl_hobbies.hobby_id
Дополнение: Я попытался установить прямую связь между GuyHobbies и GirlHobbies использованием
girl_hobbies = relationship('GirlHobbies',
primaryjoin ="and_(GuyHobbies.guy_id == Guy.id,
Match.guy_id == Guy.id ,Match.girl_id == Girl.id,
GirlHobbies.girl_id == Girl.id ,
GirlHobbies.hobby_id == Hobby.id,
GuyHobbies.hobby_id == Hobby.id)")
пока я получаю довольно ироничное сообщение об ошибке:
Could not locate any simple equality expressions involving locally mapped foreign key columns for primary join condition 'guy_hobbies.guy_id = guy.id AND match.guy_id = guy.id AND match.girl_id = girl.id AND girl_hobbies.girl_id = girl.id AND girl_hobbies.hobby_id = hobby.id AND guy_hobbies.hobby_id = hobby.id' on relationship GuyHobbies.girl_hobbies.
который отображает точно условие соединения Я хочу использовать SQLAlchemy ...