Есть простая футбольная база.
Выберите все игры с конкретным игроком, это работает:
# By Team "A"
SELECT
g.id
FROM "Game" g
JOIN "Team" t
ON g.team_a_id = t.id
JOIN "JoinTeamPlayer" j
ON t.id = j.team_id
AND j.player_id = :player
UNION
# By Team "B"
SELECT
g.id
FROM "Game" g
JOIN "Team" t
ON g.team_b_id = t.id
JOIN "JoinTeamPlayer" j
ON t.id = j.team_id
AND j.player_id = :player
Я хочу преобразовать это в API запроса SQLAlchemy
Меня смущают два внешних ключа к одному столу и то, что в команде может быть несколько игроков. Я могу оставить это так, но я уверен, что есть прекрасное решение.
SQL TABLES (Postgresql)
CREATE TABLE "Game" (
id SERIAL NOT NULL
CONSTRAINT "Game_pkey"
PRIMARY KEY,
team_a_id INTEGER NOT NULL
CONSTRAINT "Game_team_a_id_fkey"
REFERENCES "Team",
team_b_id INTEGER NOT NULL
CONSTRAINT "Game_team_b_id_fkey"
REFERENCES "Team"
);
CREATE TABLE "Team" (
id SERIAL NOT NULL
CONSTRAINT "Team_pkey"
PRIMARY KEY,
name VARCHAR NOT NULL
);
CREATE TABLE "Player" (
id SERIAL NOT NULL
CONSTRAINT "Player_pkey"
PRIMARY KEY,
name VARCHAR NOT NULL
);
CREATE TABLE "JoinTeamPlayer" (
team_id INTEGER NOT NULL
CONSTRAINT "JoinTeamPlayer_team_id_fkey"
REFERENCES "Team",
player_id INTEGER NOT NULL
CONSTRAINT "JoinTeamPlayer_player_id_fkey"
REFERENCES "Player"
);
SQLAlchemy ORM Mappers
class Base( db.Model ):
__abstract__ = True
id = Column( Integer, primary_key=True )
class Game( Base ):
team_a_id = Column( Integer, ForeignKey( 'Team.id' ), nullable=False )
team_a = relationship( 'Team', foreign_keys=team_a_id )
team_b_id = Column( Integer, ForeignKey( 'Team.id' ), nullable=False )
team_b = relationship( 'Team', foreign_keys=team_b_id )
join = Table( 'JoinTeamPlayer', Base.metadata,
Column( 'team_id', Integer, ForeignKey( 'Team.id' ), nullable=False ),
Column( 'player_id', Integer, ForeignKey( 'Player.id' ), nullable=False ) )
class Team( Base ):
name = Column( String, nullable=False )
players = relationship( 'Player', secondary=join )
class Player( Base ):
name = Column( String, nullable=False )