简体   繁体   中英

SQLAlchemy 2 columns with same foreign key 1 relationship - OR query?

I have two tables teams and matches (has more columns than shown but these are enough for this example):

class Teams(DBBase):
    __tablename__ = 'teams'
    team_id = Column(
        sqlalchemy.INTEGER,
        primary_key=True,
        autoincrement=False)
    sport_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("sports.sport_id"),
        index=True)
    team_type_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("team_types.team_type_id"),
        index=True)
    country_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("countries.country_id"),
        index=True)

class Matches(DBBase):
    __tablename__ = 'matches'
    match_id = Column(
        sqlalchemy.INTEGER,
        primary_key=True,
        autoincrement=False)
    team_0_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("teams.team_id"),
        index=True)
    team_1_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("teams.team_id"),
        index=True)
    venue_id = Column(
        sqlalchemy.INTEGER,
        sqlalchemy.ForeignKey("venues.venue_id"),
        index=True)

I would like to be able to access all of a team's matches, whether they are team_0 or team_1 (think home or away).

In raw SQL I could do something like:

SELECT * FROM matches WHERE team_0_id = 'insert team id here' OR team_1_id = 'insert team id here'

or I think even more optimally (speedwise):

SELECT * FROM matches WHERE team_0_id = 'insert team id here' 
UNION
SELECT * FROM matches WHERE team_1_id = 'insert team id here'

Now I am wondering what is the correct (if there is one) way to create a relationship on my Teams class?

I came up with the following:

matches = relationship('Matches', primary_join="or_(Teams.team_id==Matches.team_0_id, Teams.team_id==Matches.team_1_id")

However this won't make use of UNION . I also wondered if this is perhaps just bad table/DB design and I should have some sort of association table between matches and teams instead?

You can use union here, via the ORM's Query.union

home_query = session.query(Matches).filter(Matches.team_0_id == 1)

away_query = session.query(Matches).filter(Matches.team_1_id == 1)

all_matches_where_team_participated = home_query.union(away_query).all()

Where session is created from sessionmaker

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