Statcast: role belongs in the key (two-way players)
Found by inducing the real job on the server, not by review: the first chunk wrote, the second failed with 'ON CONFLICT DO UPDATE command cannot affect row a second time'. A player can legitimately appear in BOTH the batter and the pitcher feeds — two-way players, position players who pitch, pitchers who bat — so (sport, season, source_id) collapsed two real profiles into one key and a single batch hit the same row twice. Ohtani has a real batter profile and a real pitcher profile. Merging them would invent one player out of two genuinely different sets of measurements, so role goes in the primary key rather than one profile winning. Migration 031 applied; conflict target updated; a two-way case is now a test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCNgGSt5qvcLxaeQqa7Zpj
This commit is contained in:
@@ -206,7 +206,12 @@ async function refreshSeason(opts = {}) {
|
||||
const batch = rows.slice(i, i + chunk).map(toDbRow);
|
||||
const { error } = await sb
|
||||
.from('statcast_aggregates')
|
||||
.upsert(batch, { onConflict: 'sport,season,source_id' });
|
||||
// ROLE is part of the key: a two-way player has a real batter profile AND
|
||||
// a real pitcher profile, and merging them would invent one player out of
|
||||
// two genuinely different sets of measurements. (Found by inducing the
|
||||
// job: without role, one batch hit the same row twice and Postgres
|
||||
// refused the chunk.)
|
||||
.upsert(batch, { onConflict: 'sport,season,source_id,role' });
|
||||
if (error) {
|
||||
summary.ok = false;
|
||||
summary.reason = `upsert failed: ${error.message}`;
|
||||
|
||||
Reference in New Issue
Block a user