简体   繁体   中英

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 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM