sghorbal commited on
Commit
075cf25
·
1 Parent(s): 3e66851

solve type issues and default value for api calls

Browse files
alembic/versions/9f4f9ff24810_modify_match_date_type.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """add reference materialized views
2
+
3
+ Revision ID: 9f4f9ff24810
4
+ Revises: 141ff488c041
5
+ Create Date: 2025-04-22 09:53:12.677442
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ from sqlalchemy.dialects import postgresql
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = '9f4f9ff24810'
16
+ down_revision: Union[str, None] = '141ff488c041'
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Upgrade schema."""
23
+ conn = op.get_bind()
24
+
25
+ # Step 1 - Get the list of materialized views that are in the 'data' schema
26
+ views = conn.execute(sa.text("""
27
+ SELECT schemaname, matviewname
28
+ FROM pg_matviews
29
+ WHERE schemaname = 'data'
30
+ """)).fetchall()
31
+
32
+ # Step 2 - For each view, get the definition and indexes
33
+ # and store them in a list
34
+ view_data = []
35
+
36
+ for schema, view in views:
37
+ # Fetch the view definition
38
+ view_def = conn.execute(
39
+ sa.text(f"SELECT pg_get_viewdef('{schema}.{view}', true)")
40
+ ).scalar()
41
+
42
+ # Récupérer les index de la vue
43
+ indexes = conn.execute(
44
+ sa.text("""
45
+ SELECT indexname, indexdef
46
+ FROM pg_indexes
47
+ WHERE tablename = :viewname AND schemaname = :schema
48
+ """),
49
+ {"viewname": view, "schema": schema}
50
+ ).fetchall()
51
+
52
+ view_data.append({
53
+ "schema": schema,
54
+ "view": view,
55
+ "definition": view_def,
56
+ "indexes": indexes
57
+ })
58
+
59
+ # Suppress the materialized view
60
+ op.execute(f'DROP MATERIALIZED VIEW IF EXISTS {schema}.{view} CASCADE')
61
+
62
+ # Step 3 - Modify the column type in the 'match' table
63
+ op.alter_column('match', 'date',
64
+ existing_type=postgresql.TIMESTAMP(),
65
+ type_=sa.Date(),
66
+ existing_nullable=True,
67
+ schema='data')
68
+
69
+ # Step 4 - Recreate the materialized views with the new column type
70
+ # and the same definition and indexes
71
+ for view in view_data:
72
+ schema = view['schema']
73
+ name = view['view']
74
+ definition = view['definition']
75
+
76
+ op.execute(f"""
77
+ CREATE MATERIALIZED VIEW {schema}.{name} AS
78
+ {definition}
79
+ """)
80
+ # Refresh the materialized view with data
81
+ op.execute(f"REFRESH MATERIALIZED VIEW {schema}.{name}")
82
+
83
+ # Recreate the indexes
84
+ for index in view['indexes']:
85
+ op.execute(index.indexdef)
86
+
87
+
88
+ def downgrade() -> None:
89
+ """Downgrade schema."""
90
+ conn = op.get_bind()
91
+
92
+ # Step 1 - Get the list of materialized views that are in the 'data' schema
93
+ views = conn.execute(sa.text("""
94
+ SELECT schemaname, matviewname
95
+ FROM pg_matviews
96
+ WHERE schemaname = 'data'
97
+ """)).fetchall()
98
+
99
+ # Step 2 - For each view, get the definition and indexes
100
+ # and store them in a list
101
+ view_data = []
102
+
103
+ for schema, view in views:
104
+ # Fetch the view definition
105
+ view_def = conn.execute(
106
+ sa.text(f"SELECT pg_get_viewdef('{schema}.{view}', true)")
107
+ ).scalar()
108
+
109
+ # Récupérer les index de la vue
110
+ indexes = conn.execute(
111
+ sa.text("""
112
+ SELECT indexname, indexdef
113
+ FROM pg_indexes
114
+ WHERE tablename = :viewname AND schemaname = :schema
115
+ """),
116
+ {"viewname": view, "schema": schema}
117
+ ).fetchall()
118
+
119
+ view_data.append({
120
+ "schema": schema,
121
+ "view": view,
122
+ "definition": view_def,
123
+ "indexes": indexes
124
+ })
125
+
126
+ # Suppress the materialized view
127
+ op.execute(f'DROP MATERIALIZED VIEW IF EXISTS {schema}.{view} CASCADE')
128
+
129
+ # Step 3 - Modify the column type in the 'match' table
130
+ op.alter_column('match', 'date',
131
+ existing_type=sa.Date(),
132
+ type_=postgresql.TIMESTAMP(),
133
+ existing_nullable=True,
134
+ schema='data')
135
+
136
+ # Step 4 - Recreate the materialized views with the new column type
137
+ # and the same definition and indexes
138
+ for view in view_data:
139
+ schema = view['schema']
140
+ name = view['view']
141
+ definition = view['definition']
142
+
143
+ op.execute(f"""
144
+ CREATE MATERIALIZED VIEW {schema}.{name} AS
145
+ {definition}
146
+ """)
147
+ # Refresh the materialized view with data
148
+ op.execute(f"REFRESH MATERIALIZED VIEW {schema}.{name}")
149
+
150
+ # Recreate the indexes
151
+ for index in view['indexes']:
152
+ op.execute(index.indexdef)
src/entity/match.py CHANGED
@@ -1,10 +1,10 @@
1
- from sqlalchemy import Integer, String, DateTime, ForeignKey, UniqueConstraint
2
  from sqlalchemy.orm import relationship, mapped_column, Mapped
3
  from src.entity.odds import Odds, OddsApi
4
  from src.entity.player import Player, PlayerApiDetail
5
  from typing import Literal, Optional, ClassVar, List
6
  from pydantic import BaseModel, Field, ConfigDict
7
- from datetime import datetime
8
 
9
  from . import Base
10
 
@@ -20,7 +20,7 @@ class Match(Base):
20
 
21
  # Match table columns
22
  id: Mapped[int] = mapped_column(primary_key=True)
23
- date: Mapped[DateTime] = mapped_column(DateTime, nullable=True)
24
  comment: Mapped[str] = mapped_column(String, nullable=True)
25
  winner_rank: Mapped[int] = mapped_column(Integer, nullable=True)
26
  winner_points: Mapped[int] = mapped_column(Integer, nullable=True)
@@ -48,7 +48,7 @@ class Match(Base):
48
 
49
  class MatchApiBase(BaseModel):
50
  id: int
51
- date: Optional[datetime]
52
  comment: Optional[str]
53
  winner_rank: Optional[int]
54
  winner_points: Optional[int]
 
1
+ from sqlalchemy import Integer, String, Date, ForeignKey, UniqueConstraint
2
  from sqlalchemy.orm import relationship, mapped_column, Mapped
3
  from src.entity.odds import Odds, OddsApi
4
  from src.entity.player import Player, PlayerApiDetail
5
  from typing import Literal, Optional, ClassVar, List
6
  from pydantic import BaseModel, Field, ConfigDict
7
+ from datetime import date as ddate
8
 
9
  from . import Base
10
 
 
20
 
21
  # Match table columns
22
  id: Mapped[int] = mapped_column(primary_key=True)
23
+ date: Mapped[ddate] = mapped_column(Date, nullable=True)
24
  comment: Mapped[str] = mapped_column(String, nullable=True)
25
  winner_rank: Mapped[int] = mapped_column(Integer, nullable=True)
26
  winner_points: Mapped[int] = mapped_column(Integer, nullable=True)
 
48
 
49
  class MatchApiBase(BaseModel):
50
  id: int
51
+ date: Optional[ddate]
52
  comment: Optional[str]
53
  winner_rank: Optional[int]
54
  winner_points: Optional[int]
src/entity/player.py CHANGED
@@ -63,12 +63,12 @@ class PlayerApiDetail(PlayerApiBase):
63
  # -----------------------------------------------------------
64
  class CaracteristicsApi(BaseModel):
65
  id: int
66
- nationality: str
67
- last_name: str
68
- first_name: str
69
- play_hand: str
70
- back_hand: int
71
- height_cm: int
72
- weight_kg: int
73
- date_of_birth: date
74
- pro_year: int
 
63
  # -----------------------------------------------------------
64
  class CaracteristicsApi(BaseModel):
65
  id: int
66
+ nationality: Optional[str]
67
+ last_name: Optional[str]
68
+ first_name: Optional[str]
69
+ play_hand: Optional[str]
70
+ back_hand: Optional[int]
71
+ height_cm: Optional[int]
72
+ weight_kg: Optional[int]
73
+ date_of_birth: Optional[date]
74
+ pro_year: Optional[int]