Skip to content

Commit

Permalink
importer: rgl: Support combining teams
Browse files Browse the repository at this point in the history
Add support for combining teams that have been linked after already having
been imported. This occasionally happens by request.

Signed-off-by: Sean Anderson <[email protected]>
  • Loading branch information
Forty-Bot committed Apr 13, 2024
1 parent 0f8a44b commit 9acd45e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 13 deletions.
23 changes: 20 additions & 3 deletions test/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@
from trends.importer.fetch import DemoFileFetcher, ETF2LFileFetcher, FileFetcher, RGLFileFetcher
from trends.sql import db_connect, db_init, db_schema

# Pretend these two teams aren't linked so we can test combining them
class RGLFirstFetcher(RGLFileFetcher):
def get_team(self, teamid):
ret = super().get_team(teamid)
if teamid == 5574:
ret['linkedTeams'] = []
ret['fetched'] = 1
if teamid == 4882:
ret['linkedTeams'] = []
ret['fetched'] = 1
return ret

class RGLSecondFetcher(RGLFileFetcher):
def get_matchids(self):
yield 4664

def create_test_db(url):
# We use separate connections for importing because we use temporary tables which will alias
# other queries.
Expand Down Expand Up @@ -82,9 +98,10 @@ def create_test_db(url):
trends.importer.etf2l.import_etf2l(c, fetcher)

with db_connect(url) as c:
fetcher = RGLFileFetcher(dir=f"{os.path.dirname(__file__)}/rgl")
trends.importer.rgl.import_rgl(c, fetcher)

dir = f"{os.path.dirname(__file__)}/rgl"
trends.importer.rgl.import_rgl(c, RGLFirstFetcher(dir=dir))
trends.importer.rgl.import_rgl(c, RGLSecondFetcher(dir=dir),
filter=trends.importer.rgl.no_filter_matchids)
with db_connect(url) as c:
cur = c.cursor()
cur.execute("ANALYZE;")
Expand Down
45 changes: 39 additions & 6 deletions trends/importer/league.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,38 @@ def import_compdiv(c, cd):
(SELECT div_nameid FROM div_name WHERE division = %(division)s), %(tier)s
) ON CONFLICT DO NOTHING;""", cd)

def combine_teams(c, league, teamids):
"""Combine teams
Combine the teams specified into one team. This may occasionally be necessary when RGL teams are
retroactively linked.
"""

new_teamid = min(teamids)
teamids = tuple(teamid for teamid in teamids if teamid != new_teamid)
def set_constraints(behavior):
c.execute(
f"""SET CONSTRAINTS
team_player_league_teamid_fkey,
team_player_league_teamid_compid_fkey,
match_league_compid_teamid1_fkey,
match_league_compid_teamid2_fkey
{behavior};""");

set_constraints("DEFERRED")
for table, col in (
('team_comp_backing', 'teamid'),
('team_player', 'teamid'),
('match', 'teamid1'),
('match', 'teamid2'),
):
c.execute(
f"""UPDATE {table}
SET {col} = %s
WHERE league = %s AND {col} IN %s;""", (new_teamid, league, teamids))
set_constraints("IMMEDIATE")

return new_teamid

def import_team(c, t):
"""Import a team
The competition and division should already be imported. t should be a dict with the following
Expand Down Expand Up @@ -69,13 +101,14 @@ def import_team(c, t):
if teamids := t.get('rgl_teamids'):
c.execute("SELECT teamid FROM team_comp WHERE rgl_teamid IN %s GROUP BY teamid",
(teamids,))
if c.rowcount not in (0, 1):
logging.warning("Too many matching teams for linked RGL teamids %s", teamids)

if row := c.fetchone():
t['teamid'] = row[0]
if c.rowcount > 1:
logging.info("Combining RGL teamids %s", teamids)
t['teamid'] = combine_teams(c, t['league'], tuple(row[0] for row in c.fetchall()))
else:
teamid_col = min(teamids)
if row := c.fetchone():
t['teamid'] = row[0]
else:
teamid_col = min(teamids)

c.execute("INSERT INTO team_name (team) VALUES (%(name)s) ON CONFLICT DO NOTHING", t)
c.execute(
Expand Down
8 changes: 8 additions & 0 deletions trends/migrations/deferrable_teamid.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
BEGIN;
ALTER TABLE team_player
ALTER CONSTRAINT team_player_league_teamid_fkey DEFERRABLE,
ALTER CONSTRAINT team_player_league_teamid_compid_fkey DEFERRABLE;
ALTER TABLE match
ALTER CONSTRAINT match_league_compid_teamid1_fkey DEFERRABLE,
ALTER CONSTRAINT match_league_compid_teamid2_fkey DEFERRABLE;
COMMIT;
11 changes: 7 additions & 4 deletions trends/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,9 @@ CREATE TABLE IF NOT EXISTS team_player (
rostered WITH &&,
playerid WITH =
) WHERE (compid ISNULL),
FOREIGN KEY (league, teamid) REFERENCES league_team (league, teamid),
FOREIGN KEY (league, teamid, compid) REFERENCES team_comp_backing (league, teamid, compid),
FOREIGN KEY (league, teamid) REFERENCES league_team (league, teamid) DEFERRABLE,
FOREIGN KEY (league, teamid, compid)
REFERENCES team_comp_backing (league, teamid, compid) DEFERRABLE,
CHECK (league_team_per_comp(league) = (compid NOTNULL))
);

Expand Down Expand Up @@ -295,8 +296,10 @@ CREATE TABLE IF NOT EXISTS match (
FOREIGN KEY (league, round_compid, round_seq)
REFERENCES comp_round (league, compid, round_seq),
FOREIGN KEY (league, divid, round_seq) REFERENCES div_round (league, divid, round_seq),
FOREIGN KEY (league, compid, teamid1) REFERENCES team_comp_backing (league, compid, teamid),
FOREIGN KEY (league, compid, teamid2) REFERENCES team_comp_backing (league, compid, teamid),
FOREIGN KEY (league, compid, teamid1)
REFERENCES team_comp_backing (league, compid, teamid) DEFERRABLE,
FOREIGN KEY (league, compid, teamid2)
REFERENCES team_comp_backing (league, compid, teamid) DEFERRABLE,
CHECK (teamid1 < teamid2),
CHECK (league_div_optional(league) OR (divid NOTNULL)),
CHECK (league_time_optional(league) OR forfeit OR (scheduled NOTNULL)),
Expand Down

0 comments on commit 9acd45e

Please sign in to comment.