Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Alchemy Join Multiple Columns from same table

class Match(Base):
    __tablename__ = 'matches'

    id = Column(Integer, primary_key=True)
    date = Column(Date, nullable=False)
    time = Column(Time, nullable=True)
    league_id = Column(ForeignKey('leagues.id'), nullable=False, index=True)
    league = relationship('League', backref='matches')
    type = Column(enums.matches_types)
    home_team_id = Column(ForeignKey('teams.id'), nullable=False, index=True)
    home_team = relationship('Team', foreign_keys=[home_team_id], backref='home_matches')
    away_team_id = Column(ForeignKey('teams.id'), nullable=False, index=True)


class Team(Base):
    __tablename__ = 'teams'

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    country_id = Column(ForeignKey('countries.id'), nullable=False, index=True)
    country = relationship('Country', backref='teams')

I need to write a query that joins columns and teams tables displaying information of the teams information for both local and away team.

Session.query(Match.date, Match.home_team.name, Match_away_team.name).joins(Team)

This returns Can't determine join between 'matches' and 'teams'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly

like image 270
FranGoitia Avatar asked Jun 12 '26 04:06

FranGoitia


1 Answers

First, the reason your code doesn't work is because SQLAlchemy doesn't know whether you want to join to Team via home_team or away_team, so you'll have to tell it. In addition, you'll need to join to Team twice, which further complicates things.

This can be done more easily by using joinedload:

matches = session.query(Match).options(joinedload(Match.home_team),
                                       joinedload(Match.away_team))
for m in matches:
    print m.date, m.home_team, m.away_team

m.home_team and m.away_team will be loaded in the same query as m using a JOIN.

If you insist on using an explicit .join() you'll have to alias the Team entities (not tested):

home = aliased(Team)
away = aliased(Team)
q = session.query(Match.date, home, away).join(home, Match.home_team) \
                                         .join(away, Match.away_team)
for date, home_team, away_team in q:
    print date, home_team, away_team
like image 98
univerio Avatar answered Jun 13 '26 18:06

univerio