File size: 6,111 Bytes
075cf25
1bb9c62
d25bf89
 
 
fe5a14c
075cf25
1bb9c62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
075cf25
1bb9c62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fe5a14c
d25bf89
 
 
 
 
 
075cf25
d25bf89
 
 
 
 
 
 
 
 
 
 
 
 
02c056c
d25bf89
97e590c
d25bf89
 
 
 
 
fe5a14c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from sqlalchemy import Integer, String, Date, ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship, mapped_column, Mapped
from src.entity.odds import Odds, OddsApi
from src.entity.player import Player, PlayerApiDetail
from typing import Literal, Optional, ClassVar, List
from pydantic import BaseModel, Field, ConfigDict
from datetime import date as ddate

from . import Base

class Match(Base):
    """
    Match table
    """
    __tablename__ = "match"
    __table_args__ = (
        UniqueConstraint('date', 'fk_winner_id', 'fk_loser_id', name='uq_date_fk_winner_id_fk_loser_id'),
        {'schema': 'data'},
    )

    # Match table columns
    id: Mapped[int] = mapped_column(primary_key=True)
    date: Mapped[ddate] = mapped_column(Date, nullable=True)
    comment: Mapped[str] = mapped_column(String, nullable=True)
    winner_rank: Mapped[int] = mapped_column(Integer, nullable=True)
    winner_points: Mapped[int] = mapped_column(Integer, nullable=True)
    loser_rank: Mapped[int] = mapped_column(Integer, nullable=True)
    loser_points: Mapped[int] = mapped_column(Integer, nullable=True)
    tournament_name: Mapped[str] = mapped_column(String, nullable=True)
    tournament_series: Mapped[str] = mapped_column(String, nullable=True)
    tournament_surface: Mapped[str] = mapped_column(String, nullable=True)
    tournament_court: Mapped[str] = mapped_column(String, nullable=True)
    tournament_round: Mapped[str] = mapped_column(String, nullable=True)
    tournament_location: Mapped[str] = mapped_column(String, nullable=True)

    # Dependent table
    odds: Mapped[list["Odds"]] = relationship("Odds", back_populates="match", cascade="all, delete-orphan", passive_deletes=True)

    fk_winner_id: Mapped[int] = mapped_column(ForeignKey("data.player.id", ondelete="CASCADE", name='match_fk_winner_id_fkey'), nullable=False)
    fk_loser_id: Mapped[int] = mapped_column(ForeignKey("data.player.id", ondelete="CASCADE", name='match_fk_loser_id_fkey'), nullable=False)

    winner: Mapped["Player"] = relationship("Player", foreign_keys=[fk_winner_id])
    loser: Mapped["Player"] = relationship("Player", foreign_keys=[fk_loser_id])

# -----------------------------------------------------------
# Pydantic Model for Match
# -----------------------------------------------------------

class MatchApiBase(BaseModel):
    id: int
    date: Optional[ddate]
    comment: Optional[str]
    winner_rank: Optional[int]
    winner_points: Optional[int]
    loser_rank: Optional[int]
    loser_points: Optional[int]
    tournament_name: Optional[str]
    tournament_series: Optional[str]
    tournament_surface: Optional[str]
    tournament_court: Optional[str]
    tournament_round: Optional[str]
    tournament_location: Optional[str]
    fk_winner_id: int
    fk_loser_id: int
    odds: Optional[List[OddsApi]]

    model_config: ClassVar[ConfigDict] = ConfigDict(from_attributes=True)

class MatchApiDetail(MatchApiBase):
    winner: Optional[PlayerApiDetail]
    loser: Optional[PlayerApiDetail]

# -------------------------------------------------------
class RawMatch(BaseModel):
    Comment: Literal['Completed', 'Retired', 'Walkover'] = 'Completed'
    Loser: str = Field(description="The name of the loser.", json_schema_extra={"example": "'Djokovic N.'"})
    Winner: str = Field(description="The name of the winner.", json_schema_extra={"example": "'Federer R.'"})
    Round: Literal['1st Round', '2nd Round', '3rd Round', '4th Round', 'Quarterfinals', 'Semifinals', 'The Final', 'Round Robin'] = '1st Round'
    Court: Literal['Outdoor', 'Indoor'] = 'Outdoor'
    Surface: Literal['Grass', 'Carpet', 'Clay', 'Hard'] = 'Grass'
    Wsets: int = Field(description="The number of sets won by the winner.", json_schema_extra={"example": "3"})
    Lsets: int = Field(description="The number of sets won by the loser.", json_schema_extra={"example": "0"})
    Date: str = Field(description="The date of the match.", json_schema_extra={"example": "'2019-06-15'"})
    WRank: int = Field(description="The rank of the winner.", json_schema_extra={"example": "1"})
    WPts: int = Field(description="The number of points of the winner.", json_schema_extra={"example": "4000"})
    LPts: int = Field(description="The number of points of the loser.", json_schema_extra={"example": "3000"})
    LRank: int = Field(description="The rank of the loser.", json_schema_extra={"example": "2"})
    Location: str = Field(description="The location of the tournament.", json_schema_extra={"example": "'London'"})
    Series: Literal['ATP250', 'ATP500', 'Grand Slam', 'Masters 1000', 'Masters', 'Masters Cup', 'International Gold', 'International'] = 'Grand Slam'
    W1: Optional[int] = Field(description="The score of the winner in the first set.", json_schema_extra={"example": "6"})
    W2: Optional[int] = Field(description="The score of the winner in the second set.", json_schema_extra={"example": "6"})
    W3: Optional[int] = Field(description="The score of the winner in the third set.", json_schema_extra={"example": "6"})
    W4: Optional[int] = Field(description="The score of the winner in the fourth set.", json_schema_extra={"example": "None"})
    W5: Optional[int] = Field(description="The score of the winner in the fifth set.", json_schema_extra={"example": "None"})
    L1: Optional[int] = Field(description="The score of the loser in the first set.", json_schema_extra={"example": "3"})
    L2: Optional[int] = Field(description="The score of the loser in the second set.", json_schema_extra={"example": "2"})
    L3: Optional[int] = Field(description="The score of the loser in the third set.", json_schema_extra={"example": "0"})
    L4: Optional[int] = Field(description="The score of the loser in the fourth set.", json_schema_extra={"example": "None"})
    L5: Optional[int] = Field(description="The score of the loser in the fifth set.", json_schema_extra={"example": "None"})
    Tournament: str = Field(description="The name of the tournament.", json_schema_extra={"example": "Wimbledon"})
    
    model_config: ClassVar[ConfigDict] = ConfigDict(extra="allow")