I\'ve run into an issue after following the SqlAlchemy guide here.
Given the following simplified module:
class _Base():
id_ = Column(Integer, primary_
The issue is with the definition of this relationship match = relationship("MatchResult")
for the Player
class. If you completely remove this line, and use the below definitions for the relationships, all the queries you mentioned should work as expected:
class Player(Base, BlgMixin):
__tablename__ = "player"
name_ = Column(String(100))
class MatchResult(Base, BlgMixin):
__tablename__ = "match_result"
p1_id = Column(ForeignKey(Player.id_))
p2_id = Column(ForeignKey(Player.id_))
p1 = relationship(Player, foreign_keys=p1_id)
p2 = relationship(Player, foreign_keys=p2_id)
In fact, the desired select query can also be constructed, but you need to specify the relationships explicitly on JOINs:
player_1 = aliased(Player)
player_2 = aliased(Player)
q = (
dal.session
.query(
MatchResult.p1_id,
player_1.name_,
MatchResult.p2_id,
player_2.name_,
)
.join(player_1, MatchResult.p1) # explicitly specify which relationship/FK to join on
.join(player_2, MatchResult.p2) # explicitly specify which relationship/FK to join on
)
I would, however, make few more changes to the model to make it even more user-friednly:
backref
to the relationship so that it can be navigated back from the Player
property
to show all the matches of one player for both sidesModel definitions:
class Player(Base, BlgMixin):
__tablename__ = "player"
name_ = Column(String(100))
@property
def all_matches(self):
return self.matches_home + self.matches_away
class MatchResult(Base, BlgMixin):
__tablename__ = "match_result"
p1_id = Column(ForeignKey(Player.id_))
p2_id = Column(ForeignKey(Player.id_))
p1 = relationship(Player, foreign_keys=p1_id, backref="matches_home")
p2 = relationship(Player, foreign_keys=p2_id, backref="matches_away")
This will allow navigating the relationships as per below example:
p1 = session.query(Player).get(1)
print(p1)
for match in p1.all_matches:
print(" ", match)