2016-04-15 4 views
0

Ich versuche, eine Abfrage durchzuführen, die zwei Spalten aus der gleichen Spalte verbindet.SQL Alchemy Seltsames Verhalten Join mehrere Spalten aus der gleichen Tabelle

Das sind meine Modelle:

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_id = Column(ForeignKey('teams.id'), nullable=False, index=True) 
    home = relationship('Team', foreign_keys=[home_id], backref='home_matches') 
    away_id = Column(ForeignKey('teams.id'), nullable=False, index=True) 
    away = relationship('Team', foreign_keys=[away_id], backref='away_matches') 


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

Dies ist, was ich in SQLAlchemy schrieb:

self.db_match = Session.query(Match).join(home, Match.home).options(contains_eager(Match.home) 
         ).join(away, Match.away).options(contains_eager(Match.away) 
         ).join(Match.b_reference).options(contains_eager(Match.b_reference) 
         ).filter(home.name == self.match['home']['name'] 
         ).filter(away.name == self.match['away']['name'] 
         ).filter(Match.date == self.match['date']) 

Die Übersetzung, die SQLAlchemy tut, um reine SQL ist die folgende:

SELECT teams_1.name, teams_2.name, matches.id, matches_b_reference_codes.code 
FROM teams, matches JOIN teams AS teams_1 ON teams_1.id = matches.home_id 
JOIN teams AS teams_2 ON teams_2.id = matches.away_id 
JOIN matches_b_reference_codes ON matches.id = matches_b_reference_codes.match_id 
WHERE teams_1.name = 'Portland Trail Blazers' AND teams_2.name = 'Miami Heat' AND matches.date = '2011-01-09'; 

Aber das ist was ich brauche:

SELECT teams_1.name, teams_2.name, matches.id, matches_b_reference_codes.code 
**FROM matches JOIN teams AS teams_1 ON teams_1.id = matches.home_id** 
JOIN teams AS teams_2 ON teams_2.id = matches.away_id 
JOIN matches_b_reference_codes ON matches.id = matches_b_reference_codes.match_id 
WHERE teams_1.name = 'Portland Trail Blazers' AND teams_2.name = 'Miami Heat' AND matches.date = '2011-01-09'; 
+0

Was 'home' ist und was' away'? Und was ist 'Match.home' und' Match.away'? – univerio

+0

Entschuldigung, es gab einen Fehler im Modell. Ich habe es korrigiert. – FranGoitia

Antwort

1

Sie verwenden contains_eager nicht korrekt. Sie müssen den alias Parameter angeben, wenn Sie zu einem Aliasnamen sind Beitritt:

home = aliased(Team) 
away = aliased(Away) 
Session.query(Match).join(home, Match.home) \ 
        .options(contains_eager(Match.home, alias=home)) \ 
        .join(away, Match.away) \ 
        .options(contains_eager(Match.away, alias=away)) \ 
        ... \ 
        .filter(...) 
Verwandte Themen