hockey-blast-common-lib 0.1.63__py3-none-any.whl → 0.1.64__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hockey_blast_common_lib/aggregate_all_stats.py +7 -4
- hockey_blast_common_lib/aggregate_goalie_stats.py +301 -107
- hockey_blast_common_lib/aggregate_h2h_stats.py +64 -33
- hockey_blast_common_lib/aggregate_human_stats.py +565 -280
- hockey_blast_common_lib/aggregate_referee_stats.py +286 -135
- hockey_blast_common_lib/aggregate_s2s_stats.py +85 -25
- hockey_blast_common_lib/aggregate_scorekeeper_stats.py +228 -113
- hockey_blast_common_lib/aggregate_skater_stats.py +561 -238
- hockey_blast_common_lib/assign_skater_skill.py +21 -11
- hockey_blast_common_lib/db_connection.py +59 -8
- hockey_blast_common_lib/embedding_utils.py +309 -0
- hockey_blast_common_lib/h2h_models.py +150 -56
- hockey_blast_common_lib/models.py +305 -150
- hockey_blast_common_lib/options.py +30 -15
- hockey_blast_common_lib/progress_utils.py +21 -13
- hockey_blast_common_lib/skills_in_divisions.py +170 -33
- hockey_blast_common_lib/skills_propagation.py +164 -70
- hockey_blast_common_lib/stats_models.py +489 -245
- hockey_blast_common_lib/stats_utils.py +6 -3
- hockey_blast_common_lib/utils.py +89 -25
- hockey_blast_common_lib/wsgi.py +7 -5
- {hockey_blast_common_lib-0.1.63.dist-info → hockey_blast_common_lib-0.1.64.dist-info}/METADATA +1 -1
- hockey_blast_common_lib-0.1.64.dist-info/RECORD +29 -0
- hockey_blast_common_lib-0.1.63.dist-info/RECORD +0 -28
- {hockey_blast_common_lib-0.1.63.dist-info → hockey_blast_common_lib-0.1.64.dist-info}/WHEEL +0 -0
- {hockey_blast_common_lib-0.1.63.dist-info → hockey_blast_common_lib-0.1.64.dist-info}/top_level.txt +0 -0
|
@@ -2,48 +2,65 @@ from flask_sqlalchemy import SQLAlchemy
|
|
|
2
2
|
|
|
3
3
|
db = SQLAlchemy()
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
# DEPRECATED - comments
|
|
6
7
|
class Comment(db.Model):
|
|
7
|
-
__tablename__ =
|
|
8
|
+
__tablename__ = "comments"
|
|
8
9
|
id = db.Column(db.Integer, primary_key=True)
|
|
9
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
10
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"))
|
|
10
11
|
comment_text = db.Column(db.Text)
|
|
11
12
|
__table_args__ = (
|
|
12
|
-
db.UniqueConstraint(
|
|
13
|
+
db.UniqueConstraint("game_id", "comment_text", name="unique_game_comment"),
|
|
13
14
|
)
|
|
14
15
|
|
|
16
|
+
|
|
15
17
|
class Division(db.Model):
|
|
16
|
-
__tablename__ =
|
|
18
|
+
__tablename__ = "divisions"
|
|
17
19
|
id = db.Column(db.Integer, primary_key=True)
|
|
18
|
-
league_number = db.Column(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
league_number = db.Column(
|
|
21
|
+
db.Integer
|
|
22
|
+
) # TODO: Deprecate usage and remove (get this info through Season->League)
|
|
23
|
+
season_number = db.Column(
|
|
24
|
+
db.Integer
|
|
25
|
+
) # TODO: Deprecate usage and remove (get this info from Season by season_id)
|
|
26
|
+
season_id = db.Column(db.Integer, db.ForeignKey("seasons.id"))
|
|
27
|
+
level = db.Column(
|
|
28
|
+
db.String(100)
|
|
29
|
+
) # Used to display original level name, however level_id may combine some levels with different name!
|
|
30
|
+
level_id = db.Column(db.Integer, db.ForeignKey("levels.id")) # New field
|
|
31
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
24
32
|
__table_args__ = (
|
|
25
|
-
db.UniqueConstraint(
|
|
33
|
+
db.UniqueConstraint(
|
|
34
|
+
"org_id",
|
|
35
|
+
"league_number",
|
|
36
|
+
"season_number",
|
|
37
|
+
"level",
|
|
38
|
+
name="_org_league_season_level_uc",
|
|
39
|
+
),
|
|
26
40
|
)
|
|
27
41
|
|
|
42
|
+
|
|
28
43
|
class Game(db.Model):
|
|
29
|
-
__tablename__ =
|
|
44
|
+
__tablename__ = "games"
|
|
30
45
|
id = db.Column(db.Integer, primary_key=True)
|
|
31
|
-
status = db.Column(db.String(255), nullable=False, default=
|
|
32
|
-
last_update_ts = db.Column(
|
|
33
|
-
|
|
46
|
+
status = db.Column(db.String(255), nullable=False, default="")
|
|
47
|
+
last_update_ts = db.Column(
|
|
48
|
+
db.DateTime, nullable=False, default=db.func.current_timestamp()
|
|
49
|
+
)
|
|
50
|
+
division_id = db.Column(db.Integer, db.ForeignKey("divisions.id"))
|
|
34
51
|
game_number = db.Column(db.Integer)
|
|
35
52
|
date = db.Column(db.Date)
|
|
36
53
|
time = db.Column(db.Time)
|
|
37
54
|
day_of_week = db.Column(db.Integer) # 1 to 7 for Monday to Sunday
|
|
38
55
|
period_length = db.Column(db.Integer) # In minutes
|
|
39
56
|
location = db.Column(db.String(100))
|
|
40
|
-
scorekeeper_id = db.Column(db.Integer, db.ForeignKey(
|
|
41
|
-
referee_1_id = db.Column(db.Integer, db.ForeignKey(
|
|
42
|
-
referee_2_id = db.Column(db.Integer, db.ForeignKey(
|
|
43
|
-
home_goalie_id = db.Column(db.Integer, db.ForeignKey(
|
|
44
|
-
visitor_goalie_id = db.Column(db.Integer, db.ForeignKey(
|
|
45
|
-
visitor_team_id = db.Column(db.Integer, db.ForeignKey(
|
|
46
|
-
home_team_id = db.Column(db.Integer, db.ForeignKey(
|
|
57
|
+
scorekeeper_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
58
|
+
referee_1_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
59
|
+
referee_2_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
60
|
+
home_goalie_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
61
|
+
visitor_goalie_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
62
|
+
visitor_team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
63
|
+
home_team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
47
64
|
visitor_final_score = db.Column(db.Integer)
|
|
48
65
|
visitor_period_1_score = db.Column(db.Integer)
|
|
49
66
|
visitor_period_2_score = db.Column(db.Integer)
|
|
@@ -66,63 +83,89 @@ class Game(db.Model):
|
|
|
66
83
|
visitor_period_3_shots = db.Column(db.Integer)
|
|
67
84
|
visitor_ot_shots = db.Column(db.Integer, default=0)
|
|
68
85
|
visitor_so_shots = db.Column(db.Integer, default=0)
|
|
69
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
86
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
70
87
|
__table_args__ = (
|
|
71
|
-
db.UniqueConstraint(
|
|
88
|
+
db.UniqueConstraint("org_id", "game_number", name="_org_game_number_uc"),
|
|
72
89
|
)
|
|
73
90
|
|
|
91
|
+
|
|
74
92
|
class GameRoster(db.Model):
|
|
75
|
-
__tablename__ =
|
|
93
|
+
__tablename__ = "game_rosters"
|
|
76
94
|
id = db.Column(db.Integer, primary_key=True)
|
|
77
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
78
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
79
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
80
|
-
role = db.Column(
|
|
95
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"))
|
|
96
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
97
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
98
|
+
role = db.Column(
|
|
99
|
+
db.String(10)
|
|
100
|
+
) # e.g., G (goalie), C (captain), A (alternate), S (substitute)
|
|
81
101
|
jersey_number = db.Column(db.String(10)) # Player's jersey number
|
|
82
102
|
__table_args__ = (
|
|
83
|
-
db.UniqueConstraint(
|
|
103
|
+
db.UniqueConstraint(
|
|
104
|
+
"game_id", "team_id", "human_id", name="_game_team_human_uc"
|
|
105
|
+
),
|
|
84
106
|
)
|
|
85
107
|
|
|
108
|
+
|
|
86
109
|
class Goal(db.Model):
|
|
87
|
-
__tablename__ =
|
|
110
|
+
__tablename__ = "goals"
|
|
88
111
|
id = db.Column(db.Integer, primary_key=True)
|
|
89
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
90
|
-
scoring_team_id = db.Column(db.Integer, db.ForeignKey(
|
|
91
|
-
opposing_team_id = db.Column(db.Integer, db.ForeignKey(
|
|
112
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"))
|
|
113
|
+
scoring_team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
114
|
+
opposing_team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
92
115
|
period = db.Column(db.String(10)) # Can be "1", "2", "3", "OT", "SO"
|
|
93
|
-
time = db.Column(db.String(10))
|
|
94
|
-
goal_scorer_id = db.Column(db.Integer, db.ForeignKey(
|
|
95
|
-
assist_1_id = db.Column(db.Integer, db.ForeignKey(
|
|
96
|
-
assist_2_id = db.Column(db.Integer, db.ForeignKey(
|
|
97
|
-
goalie_id = db.Column(
|
|
98
|
-
|
|
116
|
+
time = db.Column(db.String(10)) # For elapsed time format
|
|
117
|
+
goal_scorer_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
118
|
+
assist_1_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
119
|
+
assist_2_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
120
|
+
goalie_id = db.Column(
|
|
121
|
+
db.Integer, db.ForeignKey("humans.id"), nullable=True
|
|
122
|
+
) # Goalie who allowed the goal (can be "Empty Net" special human)
|
|
123
|
+
special_condition = db.Column(
|
|
124
|
+
db.String(50)
|
|
125
|
+
) # e.g., PP (power play), SH (short-handed)
|
|
99
126
|
sequence_number = db.Column(db.Integer)
|
|
100
127
|
__table_args__ = (
|
|
101
|
-
db.UniqueConstraint(
|
|
102
|
-
|
|
128
|
+
db.UniqueConstraint(
|
|
129
|
+
"game_id",
|
|
130
|
+
"scoring_team_id",
|
|
131
|
+
"sequence_number",
|
|
132
|
+
name="_goal_team_sequence_uc",
|
|
133
|
+
),
|
|
134
|
+
db.UniqueConstraint(
|
|
135
|
+
"game_id",
|
|
136
|
+
"period",
|
|
137
|
+
"time",
|
|
138
|
+
"goal_scorer_id",
|
|
139
|
+
"scoring_team_id",
|
|
140
|
+
name="uq_goals_no_duplicates",
|
|
141
|
+
),
|
|
103
142
|
)
|
|
104
143
|
|
|
144
|
+
|
|
105
145
|
class Human(db.Model):
|
|
106
|
-
__tablename__ =
|
|
146
|
+
__tablename__ = "humans"
|
|
107
147
|
id = db.Column(db.Integer, primary_key=True)
|
|
108
148
|
# All name components now declared non-nullable at the ORM level. Ensure data cleanup
|
|
109
149
|
# (convert existing NULLs to '') BEFORE applying a DB migration that enforces NOT NULL.
|
|
110
150
|
# middle_name and suffix may be logically "empty" but must not be NULL; use '' for absence.
|
|
111
|
-
first_name = db.Column(db.String(100), nullable=False, default=
|
|
112
|
-
middle_name = db.Column(db.String(100), nullable=False, default=
|
|
113
|
-
last_name = db.Column(db.String(100), nullable=False, default=
|
|
114
|
-
suffix = db.Column(db.String(100), nullable=False, default=
|
|
151
|
+
first_name = db.Column(db.String(100), nullable=False, default="")
|
|
152
|
+
middle_name = db.Column(db.String(100), nullable=False, default="")
|
|
153
|
+
last_name = db.Column(db.String(100), nullable=False, default="")
|
|
154
|
+
suffix = db.Column(db.String(100), nullable=False, default="")
|
|
115
155
|
first_date = db.Column(db.Date)
|
|
116
156
|
last_date = db.Column(db.Date)
|
|
117
157
|
skater_skill_value = db.Column(db.Float, nullable=True)
|
|
118
158
|
__table_args__ = (
|
|
119
|
-
db.UniqueConstraint(
|
|
159
|
+
db.UniqueConstraint(
|
|
160
|
+
"first_name", "middle_name", "last_name", "suffix", name="_human_name_uc"
|
|
161
|
+
),
|
|
120
162
|
)
|
|
121
163
|
|
|
164
|
+
|
|
122
165
|
class HumanAlias(db.Model):
|
|
123
|
-
__tablename__ =
|
|
166
|
+
__tablename__ = "human_aliases"
|
|
124
167
|
id = db.Column(db.Integer, primary_key=True)
|
|
125
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
168
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
126
169
|
first_name = db.Column(db.String(100))
|
|
127
170
|
middle_name = db.Column(db.String(100))
|
|
128
171
|
last_name = db.Column(db.String(100))
|
|
@@ -130,67 +173,88 @@ class HumanAlias(db.Model):
|
|
|
130
173
|
first_date = db.Column(db.Date)
|
|
131
174
|
last_date = db.Column(db.Date)
|
|
132
175
|
__table_args__ = (
|
|
133
|
-
db.UniqueConstraint(
|
|
176
|
+
db.UniqueConstraint(
|
|
177
|
+
"human_id",
|
|
178
|
+
"first_name",
|
|
179
|
+
"middle_name",
|
|
180
|
+
"last_name",
|
|
181
|
+
"suffix",
|
|
182
|
+
name="_human_alias_uc",
|
|
183
|
+
),
|
|
134
184
|
)
|
|
135
185
|
|
|
186
|
+
|
|
136
187
|
class HumanInTTS(db.Model):
|
|
137
|
-
__tablename__ =
|
|
188
|
+
__tablename__ = "humans_in_tts"
|
|
138
189
|
id = db.Column(db.Integer, primary_key=True)
|
|
139
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
190
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
140
191
|
tts_id = db.Column(db.Integer)
|
|
141
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
142
|
-
__table_args__ = (
|
|
143
|
-
|
|
144
|
-
)
|
|
192
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
193
|
+
__table_args__ = (db.UniqueConstraint("org_id", "tts_id", name="_org_tts_uc"),)
|
|
194
|
+
|
|
145
195
|
|
|
146
196
|
class HumansInLevels(db.Model):
|
|
147
|
-
__tablename__ =
|
|
197
|
+
__tablename__ = "humans_in_levels"
|
|
148
198
|
id = db.Column(db.Integer, primary_key=True)
|
|
149
|
-
levels_monthly_id = db.Column(db.Integer, db.ForeignKey(
|
|
150
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
199
|
+
levels_monthly_id = db.Column(db.Integer, db.ForeignKey("levels_monthly.id"))
|
|
200
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
151
201
|
games_played = db.Column(db.Integer)
|
|
152
202
|
__table_args__ = (
|
|
153
|
-
db.UniqueConstraint(
|
|
203
|
+
db.UniqueConstraint(
|
|
204
|
+
"levels_monthly_id", "human_id", name="_levels_monthly_human_uc"
|
|
205
|
+
),
|
|
154
206
|
)
|
|
155
207
|
|
|
208
|
+
|
|
156
209
|
class HumanPrivacyOptOut(db.Model):
|
|
157
|
-
__tablename__ =
|
|
210
|
+
__tablename__ = "human_privacy_opt_outs"
|
|
158
211
|
id = db.Column(db.Integer, primary_key=True)
|
|
159
212
|
first_name = db.Column(db.String(100), nullable=False)
|
|
160
|
-
middle_name = db.Column(db.String(100), nullable=False, default=
|
|
213
|
+
middle_name = db.Column(db.String(100), nullable=False, default="")
|
|
161
214
|
last_name = db.Column(db.String(100), nullable=False)
|
|
162
|
-
suffix = db.Column(db.String(100), nullable=False, default=
|
|
163
|
-
opt_out_date = db.Column(
|
|
215
|
+
suffix = db.Column(db.String(100), nullable=False, default="")
|
|
216
|
+
opt_out_date = db.Column(
|
|
217
|
+
db.DateTime, nullable=False, default=db.func.current_timestamp()
|
|
218
|
+
)
|
|
164
219
|
notes = db.Column(db.Text, nullable=True)
|
|
165
220
|
__table_args__ = (
|
|
166
|
-
db.UniqueConstraint(
|
|
221
|
+
db.UniqueConstraint(
|
|
222
|
+
"first_name",
|
|
223
|
+
"middle_name",
|
|
224
|
+
"last_name",
|
|
225
|
+
"suffix",
|
|
226
|
+
name="_privacy_optout_name_uc",
|
|
227
|
+
),
|
|
167
228
|
)
|
|
168
229
|
|
|
230
|
+
|
|
169
231
|
class League(db.Model):
|
|
170
|
-
__tablename__ =
|
|
232
|
+
__tablename__ = "leagues"
|
|
171
233
|
id = db.Column(db.Integer, primary_key=True)
|
|
172
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
234
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
173
235
|
league_number = db.Column(db.Integer)
|
|
174
236
|
league_name = db.Column(db.String(100))
|
|
175
237
|
__table_args__ = (
|
|
176
|
-
db.UniqueConstraint(
|
|
238
|
+
db.UniqueConstraint("org_id", "league_number", name="_org_league_number_uc"),
|
|
177
239
|
)
|
|
178
240
|
|
|
241
|
+
|
|
179
242
|
class Level(db.Model):
|
|
180
|
-
__tablename__ =
|
|
243
|
+
__tablename__ = "levels"
|
|
181
244
|
id = db.Column(db.Integer, primary_key=True)
|
|
182
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
245
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
183
246
|
skill_value = db.Column(db.Float) # A number from 0 (NHL) to 100 (pedestrian)
|
|
184
247
|
level_name = db.Column(db.String(100))
|
|
185
248
|
level_alternative_name = db.Column(db.String(100))
|
|
186
249
|
is_seed = db.Column(db.Boolean, nullable=True, default=False) # New field
|
|
187
250
|
skill_propagation_sequence = db.Column(db.Integer, nullable=True, default=-1)
|
|
188
251
|
__table_args__ = (
|
|
189
|
-
db.UniqueConstraint(
|
|
252
|
+
db.UniqueConstraint("org_id", "level_name", name="_org_level_name_uc"),
|
|
190
253
|
)
|
|
191
254
|
|
|
255
|
+
|
|
192
256
|
class LevelsMonthly(db.Model):
|
|
193
|
-
__tablename__ =
|
|
257
|
+
__tablename__ = "levels_monthly"
|
|
194
258
|
id = db.Column(db.Integer, primary_key=True)
|
|
195
259
|
year = db.Column(db.Integer)
|
|
196
260
|
month = db.Column(db.Integer)
|
|
@@ -198,93 +262,130 @@ class LevelsMonthly(db.Model):
|
|
|
198
262
|
season_number = db.Column(db.Integer)
|
|
199
263
|
season_name = db.Column(db.String(100))
|
|
200
264
|
level = db.Column(db.String(100))
|
|
201
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
265
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
202
266
|
__table_args__ = (
|
|
203
|
-
db.UniqueConstraint(
|
|
267
|
+
db.UniqueConstraint(
|
|
268
|
+
"org_id",
|
|
269
|
+
"year",
|
|
270
|
+
"month",
|
|
271
|
+
"league_number",
|
|
272
|
+
"season_number",
|
|
273
|
+
"level",
|
|
274
|
+
name="_org_year_month_league_season_level_uc",
|
|
275
|
+
),
|
|
204
276
|
)
|
|
205
277
|
|
|
278
|
+
|
|
206
279
|
class OrgLeagueSeasonDates(db.Model):
|
|
207
|
-
__tablename__ =
|
|
280
|
+
__tablename__ = "org_league_season_dates"
|
|
208
281
|
id = db.Column(db.Integer, primary_key=True)
|
|
209
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
282
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
210
283
|
league_number = db.Column(db.Integer)
|
|
211
284
|
season_number = db.Column(db.Integer)
|
|
212
285
|
start_date = db.Column(db.Date)
|
|
213
286
|
end_date = db.Column(db.Date)
|
|
214
287
|
__table_args__ = (
|
|
215
|
-
db.UniqueConstraint(
|
|
216
|
-
|
|
288
|
+
db.UniqueConstraint(
|
|
289
|
+
"org_id", "league_number", "season_number", name="_org_league_season_uc_too"
|
|
290
|
+
),
|
|
291
|
+
)
|
|
292
|
+
|
|
217
293
|
|
|
218
294
|
class NamesInOrgLeagueSeason(db.Model):
|
|
219
|
-
__tablename__ =
|
|
295
|
+
__tablename__ = "names_in_org_league_season"
|
|
220
296
|
id = db.Column(db.Integer, primary_key=True)
|
|
221
|
-
org_league_season_id = db.Column(
|
|
297
|
+
org_league_season_id = db.Column(
|
|
298
|
+
db.Integer, db.ForeignKey("org_league_season_dates.id")
|
|
299
|
+
)
|
|
222
300
|
first_name = db.Column(db.String(100))
|
|
223
301
|
middle_name = db.Column(db.String(100))
|
|
224
302
|
last_name = db.Column(db.String(100))
|
|
225
303
|
first_date = db.Column(db.Date)
|
|
226
304
|
last_date = db.Column(db.Date)
|
|
227
305
|
__table_args__ = (
|
|
228
|
-
db.UniqueConstraint(
|
|
306
|
+
db.UniqueConstraint(
|
|
307
|
+
"org_league_season_id",
|
|
308
|
+
"first_name",
|
|
309
|
+
"middle_name",
|
|
310
|
+
"last_name",
|
|
311
|
+
name="_org_league_season_name_uc",
|
|
312
|
+
),
|
|
229
313
|
)
|
|
230
314
|
|
|
315
|
+
|
|
231
316
|
class NamesInTeams(db.Model):
|
|
232
|
-
__tablename__ =
|
|
317
|
+
__tablename__ = "names_in_teams"
|
|
233
318
|
id = db.Column(db.Integer, primary_key=True)
|
|
234
319
|
first_name = db.Column(db.String(100))
|
|
235
320
|
middle_name = db.Column(db.String(100))
|
|
236
321
|
last_name = db.Column(db.String(100))
|
|
237
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
322
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
238
323
|
first_date = db.Column(db.Date)
|
|
239
324
|
last_date = db.Column(db.Date)
|
|
240
325
|
__table_args__ = (
|
|
241
|
-
db.UniqueConstraint(
|
|
326
|
+
db.UniqueConstraint(
|
|
327
|
+
"team_id", "first_name", "middle_name", "last_name", name="_team_name_uc"
|
|
328
|
+
),
|
|
242
329
|
)
|
|
243
330
|
|
|
331
|
+
|
|
244
332
|
class Organization(db.Model):
|
|
245
|
-
__tablename__ =
|
|
333
|
+
__tablename__ = "organizations"
|
|
246
334
|
id = db.Column(db.Integer, primary_key=True)
|
|
247
335
|
alias = db.Column(db.String(100), unique=True)
|
|
248
336
|
organization_name = db.Column(db.String(100), unique=True)
|
|
249
337
|
website = db.Column(db.String(100), nullable=True)
|
|
250
338
|
|
|
339
|
+
|
|
251
340
|
class Penalty(db.Model):
|
|
252
|
-
__tablename__ =
|
|
341
|
+
__tablename__ = "penalties"
|
|
253
342
|
id = db.Column(db.Integer, primary_key=True)
|
|
254
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
255
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
343
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"))
|
|
344
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
256
345
|
period = db.Column(db.String(10)) # Can be "1", "2", "3", "OT", etc.
|
|
257
|
-
time = db.Column(db.String(10))
|
|
258
|
-
penalized_player_id = db.Column(db.Integer, db.ForeignKey(
|
|
346
|
+
time = db.Column(db.String(10)) # For elapsed time format
|
|
347
|
+
penalized_player_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
259
348
|
infraction = db.Column(db.String(100))
|
|
260
|
-
penalty_minutes = db.Column(
|
|
349
|
+
penalty_minutes = db.Column(
|
|
350
|
+
db.String(3)
|
|
351
|
+
) # Use this for numeric penalties like 2 minutes and GM, GS, M, PS, C, GR1
|
|
261
352
|
penalty_start = db.Column(db.String(10)) # Elapsed time for start
|
|
262
|
-
penalty_end = db.Column(
|
|
353
|
+
penalty_end = db.Column(
|
|
354
|
+
db.String(10)
|
|
355
|
+
) # Elapsed time for end, can be NULL if unknown
|
|
263
356
|
penalty_sequence_number = db.Column(db.Integer)
|
|
264
357
|
__table_args__ = (
|
|
265
|
-
db.UniqueConstraint(
|
|
358
|
+
db.UniqueConstraint(
|
|
359
|
+
"game_id",
|
|
360
|
+
"team_id",
|
|
361
|
+
"penalty_sequence_number",
|
|
362
|
+
name="_game_team_penalty_sequence_uc",
|
|
363
|
+
),
|
|
266
364
|
)
|
|
267
365
|
|
|
366
|
+
|
|
268
367
|
class PlayerRole(db.Model):
|
|
269
|
-
__tablename__ =
|
|
270
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
271
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
272
|
-
role_type = db.Column(
|
|
368
|
+
__tablename__ = "player_roles"
|
|
369
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"), primary_key=True)
|
|
370
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"), primary_key=True)
|
|
371
|
+
role_type = db.Column(
|
|
372
|
+
db.String(10), primary_key=True
|
|
373
|
+
) # e.g., G (goalie), C (captain), A (alternate), S (substitute)
|
|
273
374
|
first_date = db.Column(db.Date)
|
|
274
375
|
last_date = db.Column(db.Date)
|
|
275
|
-
__table_args__ = (
|
|
276
|
-
|
|
277
|
-
)
|
|
376
|
+
__table_args__ = (db.PrimaryKeyConstraint("team_id", "human_id", "role_type"),)
|
|
377
|
+
|
|
278
378
|
|
|
279
379
|
class RefDivision(db.Model):
|
|
280
|
-
__tablename__ =
|
|
281
|
-
division_id = db.Column(db.Integer, db.ForeignKey(
|
|
282
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
380
|
+
__tablename__ = "ref_divisions"
|
|
381
|
+
division_id = db.Column(db.Integer, db.ForeignKey("divisions.id"), primary_key=True)
|
|
382
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"), primary_key=True)
|
|
283
383
|
first_date = db.Column(db.Date)
|
|
284
384
|
last_date = db.Column(db.Date)
|
|
285
385
|
|
|
386
|
+
|
|
286
387
|
class RefereeName(db.Model):
|
|
287
|
-
__tablename__ =
|
|
388
|
+
__tablename__ = "referee_names"
|
|
288
389
|
id = db.Column(db.Integer, primary_key=True)
|
|
289
390
|
first_name = db.Column(db.String(100))
|
|
290
391
|
middle_name = db.Column(db.String(100))
|
|
@@ -292,18 +393,22 @@ class RefereeName(db.Model):
|
|
|
292
393
|
first_date = db.Column(db.Date)
|
|
293
394
|
last_date = db.Column(db.Date)
|
|
294
395
|
__table_args__ = (
|
|
295
|
-
db.UniqueConstraint(
|
|
396
|
+
db.UniqueConstraint(
|
|
397
|
+
"first_name", "middle_name", "last_name", name="_referee_name_uc"
|
|
398
|
+
),
|
|
296
399
|
)
|
|
297
400
|
|
|
401
|
+
|
|
298
402
|
class ScorekeeperDivision(db.Model):
|
|
299
|
-
__tablename__ =
|
|
300
|
-
division_id = db.Column(db.Integer, db.ForeignKey(
|
|
301
|
-
human_id = db.Column(db.Integer, db.ForeignKey(
|
|
403
|
+
__tablename__ = "scorekeeper_divisions"
|
|
404
|
+
division_id = db.Column(db.Integer, db.ForeignKey("divisions.id"), primary_key=True)
|
|
405
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"), primary_key=True)
|
|
302
406
|
first_date = db.Column(db.Date)
|
|
303
407
|
last_date = db.Column(db.Date)
|
|
304
408
|
|
|
409
|
+
|
|
305
410
|
class ScorekeeperName(db.Model):
|
|
306
|
-
__tablename__ =
|
|
411
|
+
__tablename__ = "scorekeeper_names"
|
|
307
412
|
id = db.Column(db.Integer, primary_key=True)
|
|
308
413
|
first_name = db.Column(db.String(100))
|
|
309
414
|
middle_name = db.Column(db.String(100))
|
|
@@ -311,99 +416,149 @@ class ScorekeeperName(db.Model):
|
|
|
311
416
|
first_date = db.Column(db.Date)
|
|
312
417
|
last_date = db.Column(db.Date)
|
|
313
418
|
__table_args__ = (
|
|
314
|
-
db.UniqueConstraint(
|
|
419
|
+
db.UniqueConstraint(
|
|
420
|
+
"first_name", "middle_name", "last_name", name="_scorekeeper_name_uc"
|
|
421
|
+
),
|
|
315
422
|
)
|
|
316
423
|
|
|
424
|
+
|
|
317
425
|
class Season(db.Model):
|
|
318
|
-
__tablename__ =
|
|
426
|
+
__tablename__ = "seasons"
|
|
319
427
|
id = db.Column(db.Integer, primary_key=True)
|
|
320
428
|
season_number = db.Column(db.Integer)
|
|
321
429
|
season_name = db.Column(db.String(100))
|
|
322
430
|
start_date = db.Column(db.Date)
|
|
323
431
|
end_date = db.Column(db.Date)
|
|
324
|
-
league_number = db.Column(
|
|
325
|
-
|
|
326
|
-
|
|
432
|
+
league_number = db.Column(
|
|
433
|
+
db.Integer
|
|
434
|
+
) # TODO: Deprecate usage and remove (get this info from League by league_id)
|
|
435
|
+
league_id = db.Column(db.Integer, db.ForeignKey("leagues.id"))
|
|
436
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
327
437
|
__table_args__ = (
|
|
328
|
-
db.UniqueConstraint(
|
|
438
|
+
db.UniqueConstraint(
|
|
439
|
+
"org_id", "league_number", "season_number", name="_org_league_season_uc"
|
|
440
|
+
),
|
|
329
441
|
)
|
|
330
442
|
|
|
443
|
+
|
|
331
444
|
class Shootout(db.Model):
|
|
332
|
-
__tablename__ =
|
|
445
|
+
__tablename__ = "shootout"
|
|
333
446
|
id = db.Column(db.Integer, primary_key=True)
|
|
334
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
335
|
-
shooting_team_id = db.Column(db.Integer, db.ForeignKey(
|
|
336
|
-
shooter_id = db.Column(db.Integer, db.ForeignKey(
|
|
337
|
-
goalie_id = db.Column(db.Integer, db.ForeignKey(
|
|
338
|
-
has_scored = db.Column(
|
|
447
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"))
|
|
448
|
+
shooting_team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
449
|
+
shooter_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
450
|
+
goalie_id = db.Column(db.Integer, db.ForeignKey("humans.id"))
|
|
451
|
+
has_scored = db.Column(
|
|
452
|
+
db.Boolean
|
|
453
|
+
) # Reflect if goal was scored or not during shootout
|
|
339
454
|
sequence_number = db.Column(db.Integer)
|
|
340
455
|
__table_args__ = (
|
|
341
|
-
db.UniqueConstraint(
|
|
456
|
+
db.UniqueConstraint(
|
|
457
|
+
"game_id",
|
|
458
|
+
"shooting_team_id",
|
|
459
|
+
"sequence_number",
|
|
460
|
+
name="_shootout_team_sequence_uc",
|
|
461
|
+
),
|
|
342
462
|
)
|
|
343
463
|
|
|
464
|
+
|
|
344
465
|
class Team(db.Model):
|
|
345
|
-
__tablename__ =
|
|
466
|
+
__tablename__ = "teams"
|
|
346
467
|
id = db.Column(db.Integer, primary_key=True)
|
|
347
468
|
name = db.Column(db.String(100), nullable=False)
|
|
348
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
349
|
-
__table_args__ = (
|
|
350
|
-
|
|
351
|
-
)
|
|
469
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
470
|
+
__table_args__ = (db.UniqueConstraint("org_id", "name", name="_org_team_name_uc"),)
|
|
471
|
+
|
|
352
472
|
|
|
353
473
|
class TeamDivision(db.Model):
|
|
354
|
-
__tablename__ =
|
|
474
|
+
__tablename__ = "teams_divisions"
|
|
355
475
|
id = db.Column(db.Integer, primary_key=True)
|
|
356
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
357
|
-
division_id = db.Column(db.Integer, db.ForeignKey(
|
|
476
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
477
|
+
division_id = db.Column(db.Integer, db.ForeignKey("divisions.id"))
|
|
358
478
|
__table_args__ = (
|
|
359
|
-
db.UniqueConstraint(
|
|
479
|
+
db.UniqueConstraint("team_id", "division_id", name="_team_division_uc"),
|
|
360
480
|
)
|
|
361
481
|
|
|
482
|
+
|
|
362
483
|
class TeamInTTS(db.Model):
|
|
363
|
-
__tablename__ =
|
|
484
|
+
__tablename__ = "teams_in_tts"
|
|
364
485
|
id = db.Column(db.Integer, primary_key=True)
|
|
365
|
-
team_id = db.Column(db.Integer, db.ForeignKey(
|
|
486
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"))
|
|
366
487
|
tts_team_id = db.Column(db.Integer)
|
|
367
|
-
org_id = db.Column(db.Integer, db.ForeignKey(
|
|
488
|
+
org_id = db.Column(db.Integer, db.ForeignKey("organizations.id"), nullable=False)
|
|
368
489
|
__table_args__ = (
|
|
369
|
-
db.UniqueConstraint(
|
|
490
|
+
db.UniqueConstraint(
|
|
491
|
+
"org_id", "team_id", "tts_team_id", name="_org_team_tts_uc"
|
|
492
|
+
),
|
|
370
493
|
)
|
|
371
494
|
|
|
495
|
+
|
|
372
496
|
class RequestLog(db.Model):
|
|
373
|
-
__tablename__ =
|
|
497
|
+
__tablename__ = "request_logs"
|
|
374
498
|
id = db.Column(db.Integer, primary_key=True)
|
|
375
499
|
user_agent = db.Column(db.String, nullable=False)
|
|
376
500
|
client_ip = db.Column(db.String, nullable=False)
|
|
377
501
|
path = db.Column(db.String, nullable=False)
|
|
378
502
|
timestamp = db.Column(db.DateTime, nullable=False)
|
|
379
503
|
cgi_params = db.Column(db.String, nullable=True)
|
|
380
|
-
response_time_ms = db.Column(
|
|
504
|
+
response_time_ms = db.Column(
|
|
505
|
+
db.Float, nullable=True
|
|
506
|
+
) # Response time in milliseconds
|
|
507
|
+
|
|
381
508
|
|
|
382
509
|
class GoalieSaves(db.Model):
|
|
383
|
-
__tablename__ =
|
|
510
|
+
__tablename__ = "goalie_saves"
|
|
384
511
|
id = db.Column(db.Integer, primary_key=True)
|
|
385
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
386
|
-
goalie_id = db.Column(db.Integer, db.ForeignKey(
|
|
512
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"), nullable=False)
|
|
513
|
+
goalie_id = db.Column(db.Integer, db.ForeignKey("humans.id"), nullable=False)
|
|
387
514
|
saves_count = db.Column(db.Integer, nullable=False, default=0)
|
|
388
515
|
shots_against = db.Column(db.Integer, nullable=False, default=0)
|
|
389
516
|
goals_allowed = db.Column(db.Integer, nullable=False, default=0)
|
|
390
517
|
__table_args__ = (
|
|
391
|
-
db.UniqueConstraint(
|
|
518
|
+
db.UniqueConstraint("game_id", "goalie_id", name="_game_goalie_saves_uc"),
|
|
392
519
|
)
|
|
393
520
|
|
|
521
|
+
|
|
394
522
|
class ScorekeeperSaveQuality(db.Model):
|
|
395
|
-
__tablename__ =
|
|
523
|
+
__tablename__ = "scorekeeper_save_quality"
|
|
396
524
|
id = db.Column(db.Integer, primary_key=True)
|
|
397
|
-
game_id = db.Column(db.Integer, db.ForeignKey(
|
|
398
|
-
scorekeeper_id = db.Column(db.Integer, db.ForeignKey(
|
|
525
|
+
game_id = db.Column(db.Integer, db.ForeignKey("games.id"), nullable=False)
|
|
526
|
+
scorekeeper_id = db.Column(db.Integer, db.ForeignKey("humans.id"), nullable=False)
|
|
399
527
|
total_saves_recorded = db.Column(db.Integer, nullable=False, default=0)
|
|
400
|
-
max_saves_per_5sec = db.Column(
|
|
401
|
-
|
|
402
|
-
|
|
528
|
+
max_saves_per_5sec = db.Column(
|
|
529
|
+
db.Integer, nullable=False, default=0
|
|
530
|
+
) # Highest saves in any 5-second window
|
|
531
|
+
max_saves_per_20sec = db.Column(
|
|
532
|
+
db.Integer, nullable=False, default=0
|
|
533
|
+
) # Highest saves in any 20-second window
|
|
534
|
+
saves_timestamps = db.Column(
|
|
535
|
+
db.JSON, nullable=True
|
|
536
|
+
) # JSONB with home_saves/away_saves arrays of decisecond timestamps
|
|
403
537
|
__table_args__ = (
|
|
404
|
-
db.UniqueConstraint(
|
|
538
|
+
db.UniqueConstraint(
|
|
539
|
+
"game_id", "scorekeeper_id", name="_game_scorekeeper_quality_uc"
|
|
540
|
+
),
|
|
405
541
|
)
|
|
406
542
|
|
|
543
|
+
|
|
544
|
+
class HumanEmbedding(db.Model):
|
|
545
|
+
"""Vector embeddings for semantic search of humans (players/referees/scorekeepers)."""
|
|
546
|
+
__tablename__ = "human_embeddings"
|
|
547
|
+
human_id = db.Column(db.Integer, db.ForeignKey("humans.id"), primary_key=True)
|
|
548
|
+
full_name = db.Column(db.String(255), nullable=False)
|
|
549
|
+
embedding = db.Column(db.Text, nullable=False) # pgvector type, stored as text
|
|
550
|
+
updated_at = db.Column(db.DateTime, nullable=False)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
class TeamEmbedding(db.Model):
|
|
554
|
+
"""Vector embeddings for semantic search of teams."""
|
|
555
|
+
__tablename__ = "team_embeddings"
|
|
556
|
+
team_id = db.Column(db.Integer, db.ForeignKey("teams.id"), primary_key=True)
|
|
557
|
+
team_name = db.Column(db.String(255), nullable=False)
|
|
558
|
+
embedding = db.Column(db.Text, nullable=False) # pgvector type, stored as text
|
|
559
|
+
updated_at = db.Column(db.DateTime, nullable=False)
|
|
560
|
+
|
|
561
|
+
|
|
407
562
|
# # MANUAL AMENDS HAPPEN HERE :)
|
|
408
563
|
# from db_connection import create_session
|
|
409
564
|
# session = create_session("sharksice")
|
|
@@ -415,4 +570,4 @@ class ScorekeeperSaveQuality(db.Model):
|
|
|
415
570
|
# session.commit()
|
|
416
571
|
|
|
417
572
|
|
|
418
|
-
# print("Updated!")
|
|
573
|
+
# print("Updated!")
|