
    ٰoiQ3                        d Z ddlZddlZddlmZmZmZ ddlmZ i ddddddd	d
dd
dd
ddddddddddddddddddddddi ddddddd dd!dd"dd#d$d%d$d&d$d'd(d)d(d*d(d+d,d-d,d.d,d/d0d1d0i d2d0d3d4d5d4d6d4d7d8d9d8d:d8d;d<d=d<d>d<d?d@dAd@dBd@dCdDdEdDdFdDdGdHi dIdHdJdHdKdLdMdLdNdLdOdLdPdQdRdQdSdQdTdUdVdUdWdUdXdYdZdYd[dYd\dYd]d^i d_d^d`d^dadbdcdbdddbdedbdfdgdhdgdidgdjdkdldkdmdkdndkdodpdqdpdrdpdsdti dudtdvdtdwdxdydxdzdxd{d|d}d|d~d|ddddddddddddddddddi ddddddddddddddddddddddddddddddddddi dd$dd$dd(dd(dddddddd0dd0dd4dd4dd4ddddddddddi dddddddddddd8dd8ddddddDddDddLddLddÓddÓddÓddǓi ddǓddʓddʓdd͓dd͓ddbddbddғddғddғdd֓dd֓dd֓dd֓ddۓddۓddۓi ddߓddߓddߓddߓdddddddddddddddddddddd|dd
dd
i ddddddddddddddddddddddddd dddddddddi dddd(dd(d	d
dd
dd
ddddddddddLddLddddddddddi dddddddd d!d d"d d#d$d%d$d&d'd(d'd)d*d+d*d,d*d-d*d.dbd/dbd0dғi d1dғd2dғd3d4d5d4d6d4d7dۓd8dۓd9d:d;d:d<d:d=d:d>d?d@d?dAdxdBdxdCdxdDdEdEdEdFdFdFdGdGdGdHdHdHdIZdJ Z	dK Z
dL ZedMk(  r e        yy(N  a  
Relink Player Props to Scored SportsGame Records

Props may be linked to SportsGame records that have no scores (from odds sources).
This script finds the matching scored games and updates the gameId references.

Run: python3 scripts/relink_props_to_scored_games.py
    N)datetimetimezone	timedelta)defaultdictzatlanta hawksATLhawksatlantazboston celticsBOScelticsbostonzbrooklyn netsBKNnetsbrooklynzcharlotte hornetsCHAhornets	charlottezchicago bullsCHIbullschicagozcleveland cavaliersCLE	cavalierscavs	clevelandzdallas mavericksDAL	mavericksmavsdallaszdenver nuggetsDENnuggetsdenverzdetroit pistonsDETpistonsdetroitzgolden state warriorsGSWwarriorszgolden statezhouston rocketsHOUrocketshoustonzindiana pacersINDpacersindianazlos angeles clippersLACzla clippersclipperszlos angeles lakersLALz	la lakerslakerszmemphis grizzliesMEM	grizzliesmemphisz
miami heatMIAheatmiamizmilwaukee bucksMILbucks	milwaukeezminnesota timberwolvesMINtimberwolveswolves	minnesotaznew orleans pelicansNOPpelicansznew orleansznew york knicksNYKknicksznew yorkzoklahoma city thunderOKCthunderzoklahoma cityokczorlando magicORLmagicorlandozphiladelphia 76ersPHIsixers76ersphiladelphiazphoenix sunsPHXsunsphoenixzportland trail blazersPORztrail blazersblazersportlandzsacramento kingsSACkings
sacramentozsan antonio spursSASspurszsan antonioztoronto raptorsTORraptorstorontoz	utah jazzUTAjazzutahzwashington wizardsWASwizards
washingtonzarizona cardinalsARI	cardinalsarizonazatlanta falconsfalconszbaltimore ravensBALravens	baltimorezbuffalo billsBUFbillsbuffalozcarolina panthersCARpantherscarolinazchicago bearsbearszcincinnati bengalsCINbengals
cincinnatizcleveland brownsbrownszdallas cowboyscowboyszdenver broncosbroncoszdetroit lionslionszgreen bay packersGBpackersz	green bayzhouston texanstexanszindianapolis coltscoltsindianapoliszjacksonville jaguarsJAXjaguarsjacksonvillezkansas city chiefsKCchiefszkansas cityzlas vegas raidersLVraidersz	las vegaszoakland raiderszlos angeles chargerschargerszlos angeles ramsLARramszmiami dolphinsdolphinszminnesota vikingsvikingsznew england patriotsNEpatriotsznew englandznew orleans saintsNOsaintsznew york giantsNYGgiantsznew york jetsNYJjetszphiladelphia eagleseagleszpittsburgh steelersPITsteelers
pittsburghzsan francisco 49ersSF49erszsan francisconinerszseattle seahawksSEAseahawksseattleztampa bay buccaneersTB
buccaneersbucsz	tampa bayztennessee titansTENtitans	tennesseezwashington commanders
commanderszanaheim ducksANAducksanaheimzarizona coyotescoyoteszutah hockey clubzboston bruinsbruinszbuffalo sabressabreszcalgary flamesCGYflamescalgaryzcarolina hurricanes
hurricaneszchicago blackhawks
blackhawkszcolorado avalancheCOL	avalanchecoloradoavszcolumbus blue jacketsCBJzblue jacketscolumbuszdallas starsstarszdetroit red wingsz	red wingszedmonton oilersEDMoilersedmontonzflorida panthersFLAfloridazlos angeles kingsLAKzla kingszminnesota wildwildzmontreal canadiensMTL	canadiensmontrealhabsznashville predatorsNSH	predators	nashvillepredsznew jersey devilsNJDdevilsz
new jerseyznew york islandersNYI	islandersznew york rangersNYRrangerszottawa senatorsOTTsenatorsottawasenszphiladelphia flyersflyerszpittsburgh penguinspenguinspenszsan jose sharksSJSsharkszsan josezseattle krakenkrakenzst. louis bluesSTLzst louis bluesbluesz	st. louisztampa bay lightningTBL	lightningztoronto maple leafszmaple leafsleafszvancouver canucksVANVGKWSHWPG)canucks	vancouverzvegas golden knightszgolden knightsvegaszwashington capitalscapitalscapszwinnipeg jetsr   winnipegc                     | sy| j                         j                         }|t        v r	t        |   S t        |       dk  r| j	                         r| S | j                         dd S )z#Normalize team name to abbreviationN      )lowerstripTEAM_ALIASESlenisupperupper)name
name_lowers     A/var/www/html/eventheodds/scripts/relink_props_to_scored_games.pynormalize_teamr   u   sZ    ##%J\!J''
4yA~$,,.::<    c                     d} 	 t        | d      5 }|D ]b  }|j                  d      s|j                  dd      d   j                         j                  d      j                  d      d   c cd d d        S  	 d d d        t
        j                  j                  d	d
      j                  d      d   S # 1 sw Y   ;xY w# t        $ r Y Iw xY w)Nz/var/www/html/eventheodds/.envrzSPORTS_DATABASE_URL==   "?r   SPORTS_DATABASE_URL )open
startswithsplitr   FileNotFoundErrorosenvironget)env_pathflines      r   load_db_urlr      s    /H(C  	RA R??#9:::c1-a0668>>sCII#NqQQ	R 	RR	R ::>>/4::3?BB	R 	R  s:   B? B3AB3-	B? 7B39B? 3B<8B? ?	C
Cc                  |   t        d       t        d       t        dt        j                  t        j                        j                                 t        d       t               } t        j                  |       }|j                         }t        d       |j                  d       |j                         }t        dt        |       d       |s/t        d       |j                          |j                          d	d
iS t        d       |j                  d       t        t              }|j                         D ]  }|\  }}}}	}
}t!        |      }t!        |	      }t#        dd      D ]b  }t%        |      z   }|||t'        |      f}||   j)                  ||
|d       |||t'        |      f}||   j)                  ||
|dd       d  t        dt        |       d       t        d       i }d
d
d
d}|D ]  }|\  }}}}	}t!        |      }t!        |	      }|||t'              f}|j+                  |g       }|rMt-        |fd      }|d   ||<   |dxx   dz  cc<   t        d| d| d d|d    d |d!    d"|d#    d$       |d%xx   dz  cc<   t        d&| d| d d'| d(	        t        d)|d    d*|d%           |rt        d+       |j/                         D ]F  \  }}|j                  d,||f       |j0                  }|d-xx   |z  cc<   t        d.| d/| d0|        H |j3                          t        d1|d-           t        d2       |j                  d3       |j5                         d
   }|j                  d4       |j5                         d
   }t        d5|        t        d6|        t        d7       t        d8       t        d9|d           t        d:|d%           t        d;|d-           t        d       |j                          |j                          |S )<Nz<============================================================zRELINK PROPS TO SCORED GAMESzTime: z<
[1] Finding props linked to scoreless SportsGame records...a*  
        SELECT DISTINCT
            ppl."gameId",
            sg.league,
            sg."homeTeam",
            sg."awayTeam",
            sg."gameDate"::date as game_date,
            COUNT(*) as prop_count
        FROM "PlayerPropLine" ppl
        JOIN "SportsGame" sg ON ppl."gameId" = sg.id
        WHERE ppl.result IS NULL
          AND sg."homeScore" IS NULL
          AND ppl.league IN ('nba', 'nfl', 'nhl')
        GROUP BY ppl."gameId", sg.league, sg."homeTeam", sg."awayTeam", sg."gameDate"::date
        ORDER BY sg."gameDate"::date DESC
    z  Found z scoreless games with propsz+  All props already linked to scored games!relinkedr   z$
[2] Building scored games lookup...a2  
        SELECT
            id,
            league,
            "homeTeam",
            "awayTeam",
            "gameDate"::date as game_date,
            "homeScore",
            "awayScore"
        FROM "SportsGame"
        WHERE "homeScore" IS NOT NULL
          AND league IN ('nba', 'nfl', 'nhl')
       )days)iddate
home_score
away_scoreT)r  r  r  r  swappedz	  Loaded z scored game keysz*
[3] Matching scoreless to scored games...)matchedno_matchprops_relinkedc                 :    t        | d   z
  j                        S )Nr  )absr  )m	game_dates    r   <lambda>zrun_relinkage.<locals>.<lambda>   s    C6Y9N8T8T4U r   )keyr  r	  r   z	  MATCH: z vs z (z) -> game_id z	 (score: r  -r  )r
  z  NO MATCH: z) - z propsz
  Matched: z, No match: z'
[4] Updating prop gameId references...z
                UPDATE "PlayerPropLine"
                SET "gameId" = %s
                WHERE "gameId" = %s AND result IS NULL
            r  z
  Updated z props: game_id z -> z
  Total props relinked: z!
[5] Verifying linkage results...z
        SELECT COUNT(*) FROM "PlayerPropLine" ppl
        JOIN "SportsGame" sg ON ppl."gameId" = sg.id
        WHERE ppl.result IS NULL
          AND sg."homeScore" IS NOT NULL
          AND ppl.league IN ('nba', 'nfl', 'nhl')
    z
        SELECT COUNT(*) FROM "PlayerPropLine" ppl
        JOIN "SportsGame" sg ON ppl."gameId" = sg.id
        WHERE ppl.result IS NULL
          AND sg."homeScore" IS NULL
          AND ppl.league IN ('nba', 'nfl', 'nhl')
    z   Props now linkable to scores: z"  Props still on scoreless games: z=
============================================================zRESULTS:z  Games matched: z  Games unmatched: z  Props relinked: )printr   nowr   utc	isoformatr   psycopg2connectcursorexecutefetchallr   closer   listr   ranger   strappendr   minitemsrowcountcommitfetchone)db_urlconncurscoreless_gamesscored_lookuprowgame_idleaguehomeawayr  r  	home_abbr	away_abbrdeltalookup_dater  key_swapped
relink_mapstatsold_game_id
prop_countmatches
best_matchold_idnew_idupdatedlinkablestill_scorelessr  s                                @r   run_relinkagerA     s   	(O	
()	F8<<-779:
;<	(O]FF#D
++-C 

IJKK  	  llnO	HS)**E
FG;<		

A 

12KK  	  %M||~ ILFtY
J"4(	"4(	2q\ 	E#iU&;;K9i[1ABC#%%!((	'  "9i[9IJK+&--!((/ 	0 
Ic-()):
;< 

78JqA>E `AD>VT4J"4(	"4(	y)S^<##C,W*UVJ&0&6J{#)!Ii[YKr)MR\]aRbQcclmw  yE  nF  mG  GH  IS  T`  Ia  Hb  bc  d  e*"L4	{"YKtJ<W]^_!`$ 
M%	*+<j8I7J
KL 89(..0 	NNFFKK  &!	#
 llG"#w.#Jwi'7xtF8LM	N 	*51A+B*CDE 

./KK  	 ||~a HKK  	 llnQ'O	,XJ
78	..?
@A 
/	*	eI./
01	j 12
34	u%567
89	(OIIKJJLLr   __main__)__doc__r  r   r   r   r   collectionsr   r   r   r   rA  __name__ r   r   <module>rG     s    	 2 2 #bUb#Ub,5ub eb 'b 08b U	b #E	b ,6u	b
 b
 !*5b
 3>ub Ub $Ub -6ub 5b #.ub 7=eb FQRWb b  +Eb 4:5b CKEb eb 'b 08b ub (b 1:5b Ub %/b 8Fub ub (b 1:5b eb &ub /8b Eb $1%b :DUb %b "-eb 6>ub  !b  !,U!b  5>u!b" %#b"  #b" )0#b$ u%b$ &u%b$ /:5%b& e'b& &4U'b& =Ee'b& NYZ_'b( E)b( $.u)b( 7DU)b* u+b* '+b* 0:5+b, U-b, %.u-b, 7Fu-b, OTUZ-b. U/b. $U/b. -6u/b0 %1b0 "*51b0 3:51b0 CQRW1b2 E3b2 "53b2 +4U3b4 e5b4 &5e5b4 >G5b4 PZ[`5b6 7b6  '7b6 0<U7b8 9b8 !(9b8 1>u9b: u;b: (;b: 1:5;b< =b< =b< (.u=b> %?b> "+E?b> 4@?bB CbB !,UCbB 5>uCbD uEbD (EbF GbF  (GbF 1<UGbH UIbH $UIbH -6uIbJ KbJ !+EKbJ 4>uKbL UMbL $UMbN %ObN "+EObN 4@ObP QbP  (QbR eSbR 'SbT eUbT 'UbV UWbV $UWbX YbX  )$YbX 1<TYbZ e[bZ &u[b\ %]b\ ")%]b\ 2@]b^ E_b^ $-e_b^ 6DU_b` $ab` !)$ab` 1>tabb cbb  )$cbb 1<Tcbb DUVZcbd Eebd $.uebf gbf  &ugbh eibh (ibj kbj !*5kbl Dmbl #-dmbl 5B4mbn $obn !)$obp uqbp 'qbr Usbr #Esbt 5ubt #+Eubv 5wbv #-ewbv 6B5wbx 4ybx ")$ybx 1@ybx HPQUybz {bz  *5{bz 3<U{b| D}b| #/}b| 7=d}b| EPQU}b~ b~  (b~ 1<Ub@ UAb@ %1%AbD UEbD $UEbD -6uEbF uGbF (GbF 1CEGbH UIbH %eIbJ eKbJ &uKbL eMbL &uMbL /8MbN 5ObN #/ObP %QbP ".uQbR %SbR "-eSbR 6@SbR INuSbT UUbT %3EUbT <FuUbV EWbV #EWbX YbX !,UYbZ u[bZ '[bZ 0:5[b\ ]b\  )%]b^ _b^ !+E_b` eab` $Uabb %cbb "-ecbb 6@cbb IOPUcbd 5ebd #.uebd 7B5ebd KRSXebf gbf !)%gbf 2>ugbh %ibh "-eibj kbj  )%kbl umbl )%mbl 2:5mbl CI%mbn 5obn #+Eobp 5qbp #-eqbp 6<Uqbr usbr 'sbr 0:5sbt eubt &uubv uwbv /wbv 8?wbv HSTYwbx 5ybx #.uybz 5{bz #0{bz 9@{b| }b| ,1u!UU eUEuCbJ	C\~ zO r   