import math from datetime import datetime from typing import List import logging import os from pandas import DataFrame from peewee import * from peewee import ModelSelect from playhouse.shortcuts import model_to_dict # Database configuration - supports both SQLite and PostgreSQL DATABASE_TYPE = os.environ.get("DATABASE_TYPE", "sqlite") if DATABASE_TYPE.lower() == "postgresql": from playhouse.pool import PooledPostgresqlDatabase db = PooledPostgresqlDatabase( os.environ.get("POSTGRES_DB", "pd_master"), user=os.environ.get("POSTGRES_USER", "pd_admin"), password=os.environ.get("POSTGRES_PASSWORD"), host=os.environ.get("POSTGRES_HOST", "localhost"), port=int(os.environ.get("POSTGRES_PORT", "5432")), max_connections=20, stale_timeout=300, # 5 minutes timeout=0, autoconnect=True, autorollback=True, # Automatically rollback failed transactions ) else: # Default SQLite configuration for local development db = SqliteDatabase( "storage/pd_master.db", pragmas={"journal_mode": "wal", "cache_size": -1 * 64000, "synchronous": 0}, ) date = f"{datetime.now().year}-{datetime.now().month}-{datetime.now().day}" log_level = logging.INFO if os.environ.get("LOG_LEVEL") == "INFO" else "WARN" logging.basicConfig( filename=f"logs/database/{date}.log", format="%(asctime)s - database - %(levelname)s - %(message)s", level=log_level, ) # 2025, 2005 ranked_cardsets = [24, 25, 26, 27, 28, 29] LIVE_CARDSET_ID = 27 LIVE_PROMO_CARDSET_ID = 28 CARDSETS = { "ranked": {"primary": ranked_cardsets, "human": ranked_cardsets}, "minor-league": { "primary": [27, 8], # 2005, Mario "secondary": [24], # 2025 "human": [x for x in range(1, 30)], }, "major-league": { "primary": [ 27, 28, 24, 25, 13, 14, 6, 8, ], # 2005 + Promos, 2025 + Promos, 2018 + Promos, 2012, Mario "secondary": [5, 3], # 2019, 2022 "human": ranked_cardsets, }, "hall-of-fame": {"primary": [x for x in range(1, 30)], "human": ranked_cardsets}, "flashback": { "primary": [13, 5, 1, 3, 8], # 2018, 2019, 2021, 2022, Mario "secondary": [24], # 2025 "human": [13, 5, 1, 3, 8], # 2018, 2019, 2021, 2022 }, "gauntlet-3": { "primary": [13], # 2018 "secondary": [5, 11, 9], # 2019, 2016, 2023 "human": [x for x in range(1, 30)], }, "gauntlet-4": { "primary": [3, 6, 16], # 2022, 2013, Backyard Baseball "secondary": [4, 9], # 2022 Promos, 2023 "human": [3, 4, 6, 9, 15, 16], }, "gauntlet-5": { "primary": [17, 8], # 2024, Mario "secondary": [13], # 2018 "human": [x for x in range(1, 30)], }, "gauntlet-6": { "primary": [20, 8], # 1998, Mario "secondary": [12], # 2008 "human": [x for x in range(1, 30)], }, "gauntlet-7": { "primary": [5, 23], # 2019, Brilliant Stars "secondary": [1], # 2021 "human": [x for x in range(1, 30)], }, "gauntlet-8": { "primary": [24], # 2025 "secondary": [17], "human": [24, 25, 22, 23], }, "gauntlet-9": { "primary": [27], # 2005 "secondary": [24], # 2025 }, } def model_csv_headers(this_obj, exclude=None) -> List: data = model_to_dict(this_obj, recurse=False, exclude=exclude) return [x for x in data.keys()] def model_to_csv(this_obj, exclude=None) -> List: data = model_to_dict(this_obj, recurse=False, exclude=exclude) return [x for x in data.values()] def query_to_csv(all_items: ModelSelect, exclude=None): if all_items.count() == 0: data_list = [["No data found"]] else: data_list = [model_csv_headers(all_items[0], exclude=exclude)] for x in all_items: data_list.append(model_to_csv(x, exclude=exclude)) return DataFrame(data_list).to_csv(header=False, index=False) def complex_data_to_csv(complex_data: List): if len(complex_data) == 0: data_list = [["No data found"]] else: data_list = [[x for x in complex_data[0].keys()]] for line in complex_data: logging.debug(f"line: {line}") this_row = [] for key in line: logging.debug(f"key: {key}") if line[key] is None: this_row.append("") elif isinstance(line[key], dict): if "name" in line[key]: this_row.append(line[key]["name"]) elif "abbrev" in line[key]: this_row.append(line[key]["abbrev"]) else: this_row.append(line[key]["id"]) elif isinstance(line[key], int) and line[key] > 100000000: this_row.append(f"'{line[key]}") elif isinstance(line[key], str) and "," in line[key]: this_row.append(line[key].replace(",", "-_-")) else: this_row.append(line[key]) data_list.append(this_row) return DataFrame(data_list).to_csv(header=False, index=False) class BaseModel(Model): class Meta: database = db class Current(BaseModel): season = IntegerField() week = IntegerField(default=0) gsheet_template = CharField() gsheet_version = CharField() live_scoreboard = IntegerField() class Meta: database = db table_name = "current" @staticmethod def latest(): latest_current = Current.select().order_by(-Current.id).get() return latest_current db.create_tables([Current]) class Rarity(BaseModel): value = IntegerField() name = CharField(unique=True) color = CharField() class Meta: database = db table_name = "rarity" def __str__(self): return self.name db.create_tables([Rarity]) class Event(BaseModel): name = CharField() short_desc = CharField(null=True) url = CharField(null=True) long_desc = CharField(null=True) thumbnail = CharField(null=True) active = BooleanField(default=False) class Meta: database = db table_name = "event" db.create_tables([Event]) class Cardset(BaseModel): name = CharField() description = CharField() event = ForeignKeyField(Event, null=True) for_purchase = BooleanField(default=True) # for_purchase total_cards = IntegerField() in_packs = BooleanField(default=True) ranked_legal = BooleanField(default=True) class Meta: database = db table_name = "cardset" def __str__(self): return self.name db.create_tables([Cardset]) class MlbPlayer(BaseModel): first_name = CharField() last_name = CharField() key_fangraphs = IntegerField(null=True) key_bbref = CharField(null=True) key_retro = CharField(null=True) key_mlbam = IntegerField(null=True) offense_col = IntegerField(default=1) class Meta: database = db table_name = "mlbplayer" db.create_tables([MlbPlayer]) class Player(BaseModel): player_id = IntegerField(primary_key=True) p_name = CharField() cost = IntegerField(default=0) image = CharField() image2 = CharField(null=True) mlbclub = CharField() franchise = CharField() cardset = ForeignKeyField(Cardset) set_num = IntegerField() rarity = ForeignKeyField(Rarity) pos_1 = CharField() pos_2 = CharField(null=True) pos_3 = CharField(null=True) pos_4 = CharField(null=True) pos_5 = CharField(null=True) pos_6 = CharField(null=True) pos_7 = CharField(null=True) pos_8 = CharField(null=True) headshot = CharField(null=True) vanity_card = CharField(null=True) strat_code = CharField(null=True) bbref_id = CharField(null=True) fangr_id = CharField(null=True) description = CharField() quantity = IntegerField(default=999) mlbplayer = ForeignKeyField(MlbPlayer, null=True) def __str__(self): return f"{self.cardset} {self.p_name} ({self.rarity.name})" # def __eq__(self, other): # if self.cardset.id == other.cardset.id and self.name == other.name: # return True # else: # return False def __lt__(self, other): if self.wara < other.wara: return True elif self.wara > other.wara: return False elif self.name < other.name: return True else: return False def get_all_pos(self): all_pos = [] if self.pos_1 and self.pos_1 != "CP": all_pos.append(self.pos_1) if self.pos_2 and self.pos_2 != "CP": all_pos.append(self.pos_2) if self.pos_3 and self.pos_3 != "CP": all_pos.append(self.pos_3) if self.pos_4 and self.pos_4 != "CP": all_pos.append(self.pos_4) if self.pos_5 and self.pos_5 != "CP": all_pos.append(self.pos_5) if self.pos_6 and self.pos_6 != "CP": all_pos.append(self.pos_6) if self.pos_7 and self.pos_7 != "CP": all_pos.append(self.pos_7) if self.pos_8 and self.pos_8 != "CP": all_pos.append(self.pos_8) return all_pos def change_on_sell(self): # caps = { # 'replacement': 15, # 'reserve': 50, # 'starter': 200, # 'all-star': 750, # 'mvp': 2500, # 'hof': 999999999 # } logging.info(f"{self.p_name} cost changing from: {self.cost}") self.cost = max(math.floor(self.cost * 0.95), 1) # if self.quantity != 999: # self.quantity += 1 logging.info(f"{self.p_name} cost now: {self.cost}") self.save() def change_on_buy(self): logging.info(f"{self.p_name} cost changing from: {self.cost}") self.cost = math.ceil(self.cost * 1.1) # if self.quantity != 999: # self.quantity -= 1 logging.info(f"{self.p_name} cost now: {self.cost}") self.save() class Meta: database = db table_name = "player" db.create_tables([Player]) class Team(BaseModel): abbrev = CharField(max_length=20) # Gauntlet teams use prefixes like "Gauntlet-NCB" sname = CharField(max_length=100) lname = CharField(max_length=255) gmid = IntegerField() gmname = CharField() gsheet = CharField() wallet = IntegerField() team_value = IntegerField() collection_value = IntegerField() logo = CharField(null=True) color = CharField(null=True) season = IntegerField() event = ForeignKeyField(Event, null=True) career = IntegerField(default=0) ranking = IntegerField(default=1000) has_guide = BooleanField(default=False) is_ai = IntegerField(null=True) def __str__(self): return f"S{self.season} {self.lname}" @staticmethod def get_by_owner(gmid, season=None): if not season: season = Current.get().season team = Team.get_or_none((Team.gmid == gmid) & (Team.season == season)) if not team: return None return team @staticmethod def select_season(season=None): if not season: season = Current.get().season return Team.select().where(Team.season == season) @staticmethod def get_season(abbrev, season=None): if not season: season = Current.get().season return Team.get_or_none(Team.season == season, Team.abbrev == abbrev.upper()) def team_hash(self): hash_string = f"{self.sname[-1]}{self.gmid / 6950123:.0f}{self.sname[-2]}{self.gmid / 42069123:.0f}" logging.info(f"string: {hash_string}") return hash_string class Meta: database = db table_name = "team" db.create_tables([Team]) class PackType(BaseModel): name = CharField() card_count = IntegerField() description = CharField() cost = IntegerField() available = BooleanField(default=True) class Meta: database = db table_name = "packtype" db.create_tables([PackType]) class Pack(BaseModel): team = ForeignKeyField(Team) pack_type = ForeignKeyField(PackType) pack_team = ForeignKeyField(Team, null=True) pack_cardset = ForeignKeyField(Cardset, null=True) open_time = DateTimeField(null=True) class Meta: database = db table_name = "pack" db.create_tables([Pack]) class Card(BaseModel): player = ForeignKeyField(Player, null=True) team = ForeignKeyField(Team, null=True) pack = ForeignKeyField(Pack, null=True) value = IntegerField(default=0) def __str__(self): if self.player: return f"{self.player} - {self.team.sname}" else: return f"Blank - {self.team.sname}" @staticmethod def select_season(season): return Card.select().join(Team).where(Card.team.season == season) class Meta: database = db table_name = "card" db.create_tables([Card]) class Roster(BaseModel): team = ForeignKeyField(Team) name = CharField() roster_num = IntegerField() card_1 = ForeignKeyField(Card) card_2 = ForeignKeyField(Card) card_3 = ForeignKeyField(Card) card_4 = ForeignKeyField(Card) card_5 = ForeignKeyField(Card) card_6 = ForeignKeyField(Card) card_7 = ForeignKeyField(Card) card_8 = ForeignKeyField(Card) card_9 = ForeignKeyField(Card) card_10 = ForeignKeyField(Card) card_11 = ForeignKeyField(Card) card_12 = ForeignKeyField(Card) card_13 = ForeignKeyField(Card) card_14 = ForeignKeyField(Card) card_15 = ForeignKeyField(Card) card_16 = ForeignKeyField(Card) card_17 = ForeignKeyField(Card) card_18 = ForeignKeyField(Card) card_19 = ForeignKeyField(Card) card_20 = ForeignKeyField(Card) card_21 = ForeignKeyField(Card) card_22 = ForeignKeyField(Card) card_23 = ForeignKeyField(Card) card_24 = ForeignKeyField(Card) card_25 = ForeignKeyField(Card) card_26 = ForeignKeyField(Card) def __str__(self): return f"{self.team} Roster" # def get_cards(self, team): # all_cards = Card.select().where(Card.roster == self) # this_roster = [] # return [this_roster.card1, this_roster.card2, this_roster.card3, this_roster.card4, this_roster.card5, # this_roster.card6, this_roster.card7, this_roster.card8, this_roster.card9, this_roster.card10, # this_roster.card11, this_roster.card12, this_roster.card13, this_roster.card14, this_roster.card15, # this_roster.card16, this_roster.card17, this_roster.card18, this_roster.card19, this_roster.card20, # this_roster.card21, this_roster.card22, this_roster.card23, this_roster.card24, this_roster.card25, # this_roster.card26] class Meta: database = db table_name = "roster" class Result(BaseModel): away_team = ForeignKeyField(Team) home_team = ForeignKeyField(Team) away_score = IntegerField() home_score = IntegerField() away_team_value = IntegerField(null=True) home_team_value = IntegerField(null=True) away_team_ranking = IntegerField(null=True) home_team_ranking = IntegerField(null=True) scorecard = CharField() week = IntegerField() season = IntegerField() ranked = BooleanField() short_game = BooleanField() game_type = CharField(null=True) @staticmethod def select_season(season=None): if not season: season = Current.get().season return Result.select().where(Result.season == season) class Meta: database = db table_name = "result" class BattingStat(BaseModel): card = ForeignKeyField(Card) team = ForeignKeyField(Team) roster_num = IntegerField() vs_team = ForeignKeyField(Team) result = ForeignKeyField(Result, null=True) pos = CharField() pa = IntegerField() ab = IntegerField() run = IntegerField() hit = IntegerField() rbi = IntegerField() double = IntegerField() triple = IntegerField() hr = IntegerField() bb = IntegerField() so = IntegerField() hbp = IntegerField() sac = IntegerField() ibb = IntegerField() gidp = IntegerField() sb = IntegerField() cs = IntegerField() bphr = IntegerField() bpfo = IntegerField() bp1b = IntegerField() bplo = IntegerField() xch = IntegerField() xhit = IntegerField() error = IntegerField() pb = IntegerField() sbc = IntegerField() csc = IntegerField() week = IntegerField() season = IntegerField() created = DateTimeField() game_id = IntegerField() class Meta: database = db table_name = "battingstat" class PitchingStat(BaseModel): card = ForeignKeyField(Card) team = ForeignKeyField(Team) roster_num = IntegerField() vs_team = ForeignKeyField(Team) result = ForeignKeyField(Result, null=True) ip = FloatField() hit = IntegerField() run = IntegerField() erun = IntegerField() so = IntegerField() bb = IntegerField() hbp = IntegerField() wp = IntegerField() balk = IntegerField() hr = IntegerField() ir = IntegerField() irs = IntegerField() gs = IntegerField() win = IntegerField() loss = IntegerField() hold = IntegerField() sv = IntegerField() bsv = IntegerField() week = IntegerField() season = IntegerField() created = DateTimeField() game_id = IntegerField() class Meta: database = db table_name = "pitchingstat" class Award(BaseModel): name = CharField() season = IntegerField() timing = CharField(default="In-Season") card = ForeignKeyField(Card, null=True) team = ForeignKeyField(Team, null=True) image = CharField(null=True) class Meta: database = db table_name = "award" class Paperdex(BaseModel): team = ForeignKeyField(Team) player = ForeignKeyField(Player) created = DateTimeField(default=int(datetime.timestamp(datetime.now()) * 1000)) class Meta: database = db table_name = "paperdex" # def add_to_paperdex(self, team, cards: list): # for x in players: # if not isinstance(x, Card): # raise TypeError(f'The Pokedex can only take a list of Player or Card objects') # # Paperdex.get_or_create(team=team, player=player) class Reward(BaseModel): name = CharField(null=True) season = IntegerField() week = IntegerField() team = ForeignKeyField(Team) created = DateTimeField() class Meta: database = db table_name = "reward" class GameRewards(BaseModel): name = CharField() pack_type = ForeignKeyField(PackType, null=True) player = ForeignKeyField(Player, null=True) money = IntegerField(null=True) class Meta: database = db table_name = "gamerewards" class Notification(BaseModel): created = DateTimeField() title = CharField() desc = CharField(null=True) field_name = CharField() message = CharField() about = CharField() # f'{Topic}-{Object ID}' ack = BooleanField(default=False) class Meta: database = db table_name = "notification" class GauntletReward(BaseModel): name = CharField() gauntlet = ForeignKeyField(Event) reward = ForeignKeyField(GameRewards) win_num = IntegerField() loss_max = IntegerField(default=1) class Meta: database = db table_name = "gauntletreward" class GauntletRun(BaseModel): team = ForeignKeyField(Team) gauntlet = ForeignKeyField(Event) wins = IntegerField(default=0) losses = IntegerField(default=0) gsheet = CharField(null=True) created = DateTimeField(default=int(datetime.timestamp(datetime.now()) * 1000)) ended = DateTimeField(default=0) class Meta: database = db table_name = "gauntletrun" db.create_tables( [ Roster, BattingStat, PitchingStat, Result, Award, Paperdex, Reward, GameRewards, Notification, GauntletReward, GauntletRun, ] ) class BattingCard(BaseModel): player = ForeignKeyField(Player) variant = IntegerField() steal_low = IntegerField() steal_high = IntegerField() steal_auto = BooleanField() steal_jump = FloatField() bunting = CharField() hit_and_run = CharField() running = IntegerField() offense_col = IntegerField() hand = CharField(default="R") class Meta: database = db table_name = "battingcard" bc_index = ModelIndex( BattingCard, (BattingCard.player, BattingCard.variant), unique=True ) BattingCard.add_index(bc_index) class BattingCardRatings(BaseModel): battingcard = ForeignKeyField(BattingCard) vs_hand = CharField(default="R") pull_rate = FloatField() center_rate = FloatField() slap_rate = FloatField() homerun = FloatField() bp_homerun = FloatField() triple = FloatField() double_three = FloatField() double_two = FloatField() double_pull = FloatField() single_two = FloatField() single_one = FloatField() single_center = FloatField() bp_single = FloatField() hbp = FloatField() walk = FloatField() strikeout = FloatField() lineout = FloatField() popout = FloatField() flyout_a = FloatField() flyout_bq = FloatField() flyout_lf_b = FloatField() flyout_rf_b = FloatField() groundout_a = FloatField() groundout_b = FloatField() groundout_c = FloatField() avg = FloatField(null=True) obp = FloatField(null=True) slg = FloatField(null=True) class Meta: database = db table_name = "battingcardratings" bcr_index = ModelIndex( BattingCardRatings, (BattingCardRatings.battingcard, BattingCardRatings.vs_hand), unique=True, ) BattingCardRatings.add_index(bcr_index) class PitchingCard(BaseModel): player = ForeignKeyField(Player) variant = IntegerField() balk = IntegerField() wild_pitch = IntegerField() hold = IntegerField() starter_rating = IntegerField() relief_rating = IntegerField() closer_rating = IntegerField(null=True) batting = CharField(null=True) offense_col = IntegerField() hand = CharField(default="R") class Meta: database = db table_name = "pitchingcard" pc_index = ModelIndex( PitchingCard, (PitchingCard.player, PitchingCard.variant), unique=True ) PitchingCard.add_index(pc_index) class PitchingCardRatings(BaseModel): pitchingcard = ForeignKeyField(PitchingCard) vs_hand = CharField(default="R") homerun = FloatField() bp_homerun = FloatField() triple = FloatField() double_three = FloatField() double_two = FloatField() double_cf = FloatField() single_two = FloatField() single_one = FloatField() single_center = FloatField() bp_single = FloatField() hbp = FloatField() walk = FloatField() strikeout = FloatField() flyout_lf_b = FloatField() flyout_cf_b = FloatField() flyout_rf_b = FloatField() groundout_a = FloatField() groundout_b = FloatField() xcheck_p = FloatField() xcheck_c = FloatField() xcheck_1b = FloatField() xcheck_2b = FloatField() xcheck_3b = FloatField() xcheck_ss = FloatField() xcheck_lf = FloatField() xcheck_cf = FloatField() xcheck_rf = FloatField() avg = FloatField(null=True) obp = FloatField(null=True) slg = FloatField(null=True) class Meta: database = db table_name = "pitchingcardratings" pcr_index = ModelIndex( PitchingCardRatings, (PitchingCardRatings.pitchingcard, PitchingCardRatings.vs_hand), unique=True, ) PitchingCardRatings.add_index(pcr_index) class CardPosition(BaseModel): player = ForeignKeyField(Player) variant = IntegerField() position = CharField() innings = IntegerField() range = IntegerField() error = IntegerField() arm = IntegerField(null=True) pb = IntegerField(null=True) overthrow = IntegerField(null=True) class Meta: database = db table_name = "cardposition" pos_index = ModelIndex( CardPosition, (CardPosition.player, CardPosition.variant, CardPosition.position), unique=True, ) CardPosition.add_index(pos_index) db.create_tables( [BattingCard, BattingCardRatings, PitchingCard, PitchingCardRatings, CardPosition] ) class StratGame(BaseModel): season = IntegerField() game_type = CharField() away_team = ForeignKeyField(Team) home_team = ForeignKeyField(Team) week = IntegerField(default=1) away_score = IntegerField(default=0) home_score = IntegerField(default=0) away_team_value = IntegerField(null=True) home_team_value = IntegerField(null=True) away_team_ranking = IntegerField(null=True) home_team_ranking = IntegerField(null=True) ranked = BooleanField(default=False) short_game = BooleanField(default=False) forfeit = BooleanField(default=False) class Meta: database = db table_name = "stratgame" class StratPlay(BaseModel): game = ForeignKeyField(StratGame) play_num = IntegerField() batter = ForeignKeyField(Player, null=True) batter_team = ForeignKeyField(Team, null=True) pitcher = ForeignKeyField(Player) pitcher_team = ForeignKeyField(Team) on_base_code = CharField() inning_half = CharField() inning_num = IntegerField() batting_order = IntegerField() starting_outs = IntegerField() away_score = IntegerField() home_score = IntegerField() batter_pos = CharField(null=True) # These _final fields track the base this runner advances to post-play (None) if out on_first = ForeignKeyField(Player, null=True) on_first_final = IntegerField(null=True) on_second = ForeignKeyField(Player, null=True) on_second_final = IntegerField(null=True) on_third = ForeignKeyField(Player, null=True) on_third_final = IntegerField(null=True) batter_final = IntegerField(null=True) pa = IntegerField(default=0) ab = IntegerField(default=0) e_run = IntegerField(default=0) run = IntegerField(default=0) hit = IntegerField(default=0) rbi = IntegerField(default=0) double = IntegerField(default=0) triple = IntegerField(default=0) homerun = IntegerField(default=0) bb = IntegerField(default=0) so = IntegerField(default=0) hbp = IntegerField(default=0) sac = IntegerField(default=0) ibb = IntegerField(default=0) gidp = IntegerField(default=0) bphr = IntegerField(default=0) bpfo = IntegerField(default=0) bp1b = IntegerField(default=0) bplo = IntegerField(default=0) sb = IntegerField(default=0) cs = IntegerField(default=0) outs = IntegerField(default=0) wpa = FloatField(default=0.0) re24 = FloatField(default=0.0) # These fields are only required if the play is an x-check or baserunning play catcher = ForeignKeyField(Player, null=True) catcher_team = ForeignKeyField(Team, null=True) defender = ForeignKeyField(Player, null=True) defender_team = ForeignKeyField(Team, null=True) runner = ForeignKeyField(Player, null=True) runner_team = ForeignKeyField(Team, null=True) check_pos = CharField(null=True) error = IntegerField(default=0) wild_pitch = IntegerField(default=0) passed_ball = IntegerField(default=0) pick_off = IntegerField(default=0) balk = IntegerField(default=0) is_go_ahead = BooleanField(default=False) is_tied = BooleanField(default=False) is_new_inning = BooleanField(default=False) class Meta: database = db table_name = "stratplay" # Unique index for StratPlay - a play number should be unique within a game # Required for PostgreSQL on_conflict() upsert operations stratplay_index = ModelIndex( StratPlay, (StratPlay.game, StratPlay.play_num), unique=True ) StratPlay.add_index(stratplay_index) class Decision(BaseModel): season = IntegerField() game = ForeignKeyField(StratGame) pitcher = ForeignKeyField(Player) pitcher_team = ForeignKeyField(Team) week = IntegerField(default=1) win = IntegerField(default=0) loss = IntegerField(default=0) hold = IntegerField(default=0) is_save = IntegerField(default=0) b_save = IntegerField(default=0) irunners = IntegerField(default=0) irunners_scored = IntegerField(default=0) rest_ip = FloatField(default=0.0) rest_required = IntegerField(default=0) is_start = BooleanField(default=False) class Meta: database = db table_name = "decision" # Unique index for Decision - one decision per pitcher per game # Required for PostgreSQL on_conflict() upsert operations decision_index = ModelIndex(Decision, (Decision.game, Decision.pitcher), unique=True) Decision.add_index(decision_index) db.create_tables([StratGame, StratPlay, Decision]) db.close() # scout_db = SqliteDatabase( # 'storage/card_creation.db', # pragmas={ # 'journal_mode': 'wal', # 'cache_size': -1 * 64000, # 'synchronous': 0 # } # ) # # # class BaseModelScout(Model): # class Meta: # database = scout_db # # # class ScoutCardset(BaseModelScout): # set_title = CharField() # set_subtitle = CharField(null=True) # # # class ScoutPlayer(BaseModelScout): # sba_id = IntegerField(primary_key=True) # name = CharField() # fg_id = IntegerField() # br_id = CharField() # offense_col = IntegerField() # hand = CharField(default='R') # # # scout_db.create_tables([ScoutCardset, ScoutPlayer]) # # # class BatterRatings(BaseModelScout): # id = CharField(unique=True, primary_key=True) # player = ForeignKeyField(ScoutPlayer) # cardset = ForeignKeyField(ScoutCardset) # vs_hand = FloatField() # is_prep = BooleanField() # homerun = FloatField() # bp_homerun = FloatField() # triple = FloatField() # double_three = FloatField() # double_two = FloatField() # double_pull = FloatField() # single_two = FloatField() # single_one = FloatField() # single_center = FloatField() # bp_single = FloatField() # hbp = FloatField() # walk = FloatField() # strikeout = FloatField() # lineout = FloatField() # popout = FloatField() # flyout_a = FloatField() # flyout_bq = FloatField() # flyout_lf_b = FloatField() # flyout_rf_b = FloatField() # groundout_a = FloatField() # groundout_b = FloatField() # groundout_c = FloatField() # avg = FloatField(null=True) # obp = FloatField(null=True) # slg = FloatField(null=True) # # # class PitcherRatings(BaseModelScout): # id = CharField(unique=True, primary_key=True) # player = ForeignKeyField(ScoutPlayer) # cardset = ForeignKeyField(ScoutCardset) # vs_hand = CharField() # is_prep = BooleanField() # homerun = FloatField() # bp_homerun = FloatField() # triple = FloatField() # double_three = FloatField() # double_two = FloatField() # double_cf = FloatField() # single_two = FloatField() # single_one = FloatField() # single_center = FloatField() # bp_single = FloatField() # hbp = FloatField() # walk = FloatField() # strikeout = FloatField() # fo_slap = FloatField() # fo_center = FloatField() # groundout_a = FloatField() # groundout_b = FloatField() # xcheck_p = FloatField() # xcheck_c = FloatField() # xcheck_1b = FloatField() # xcheck_2b = FloatField() # xcheck_3b = FloatField() # xcheck_ss = FloatField() # xcheck_lf = FloatField() # xcheck_cf = FloatField() # xcheck_rf = FloatField() # avg = FloatField(null=True) # obp = FloatField(null=True) # slg = FloatField(null=True) # # # # scout_db.create_tables([BatterRatings, PitcherRatings]) # # # class CardColumns(BaseModelScout): # id = CharField(unique=True, primary_key=True) # player = ForeignKeyField(ScoutPlayer) # hand = CharField() # b_ratings = ForeignKeyField(BatterRatings, null=True) # p_ratings = ForeignKeyField(PitcherRatings, null=True) # one_dice = CharField() # one_results = CharField() # one_splits = CharField() # two_dice = CharField() # two_results = CharField() # two_splits = CharField() # three_dice = CharField() # three_results = CharField() # three_splits = CharField() # # # class Position(BaseModelScout): # player = ForeignKeyField(ScoutPlayer) # cardset = ForeignKeyField(ScoutCardset) # position = CharField() # innings = IntegerField() # range = IntegerField() # error = IntegerField() # arm = CharField(null=True) # pb = IntegerField(null=True) # overthrow = IntegerField(null=True) # # # class BatterData(BaseModelScout): # player = ForeignKeyField(ScoutPlayer) # cardset = ForeignKeyField(ScoutCardset) # stealing = CharField() # st_low = IntegerField() # st_high = IntegerField() # st_auto = BooleanField() # st_jump = FloatField() # bunting = CharField(null=True) # hit_and_run = CharField(null=True) # running = CharField() # # # class PitcherData(BaseModelScout): # player = ForeignKeyField(ScoutPlayer) # cardset = ForeignKeyField(ScoutCardset) # balk = IntegerField(null=True) # wild_pitch = IntegerField(null=True) # hold = CharField() # starter_rating = IntegerField() # relief_rating = IntegerField() # closer_rating = IntegerField(null=True) # batting = CharField(null=True) # # # scout_db.create_tables([CardColumns, Position, BatterData, PitcherData]) # # # class CardOutput(BaseModelScout): # name = CharField() # hand = CharField() # positions = CharField() # stealing = CharField() # bunting = CharField() # hitandrun = CharField() # running = CharField() # # # scout_db.close()