Skip to content

Commit 920b5ee

Browse files
committed
feat(sqlalchemy): index and defer all fks
1 parent 01d2f61 commit 920b5ee

File tree

2 files changed

+310
-9
lines changed

2 files changed

+310
-9
lines changed
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
"""
2+
index and defer all fks.
3+
4+
Revision ID: 3a1d48a54125
5+
Revises: e8f293cdc7bd
6+
Create Date: 2025-06-28 08:42:46.903102
7+
8+
"""
9+
10+
from collections.abc import Sequence
11+
12+
from alembic import op
13+
14+
15+
revision: str = "3a1d48a54125"
16+
down_revision: str | None = "e8f293cdc7bd"
17+
branch_labels: str | Sequence[str] | None = None
18+
depends_on: str | Sequence[str] | None = None
19+
20+
21+
def upgrade() -> None:
22+
# ### commands auto generated by Alembic - please adjust! ###
23+
op.create_index(
24+
op.f("ix_cells_filler_id"), "cells", ["filler_id"], unique=False,
25+
)
26+
op.create_index(
27+
op.f("ix_cells_game_id"), "cells", ["game_id"], unique=False,
28+
)
29+
op.drop_constraint(
30+
op.f("cells_filler_id_fkey"), "cells", type_="foreignkey",
31+
)
32+
op.drop_constraint(op.f("cells_game_id_fkey"), "cells", type_="foreignkey")
33+
op.create_foreign_key(
34+
"cells_filler_id_fkey",
35+
"cells",
36+
"players",
37+
["filler_id"],
38+
["id"],
39+
initially="DEFERRED",
40+
deferrable=True,
41+
)
42+
op.create_foreign_key(
43+
"cells_game_id_fkey",
44+
"cells",
45+
"games",
46+
["game_id"],
47+
["id"],
48+
initially="DEFERRED",
49+
deferrable=True,
50+
)
51+
op.create_index(
52+
op.f("ix_game_results_canceler_id"),
53+
"game_results",
54+
["canceler_id"],
55+
unique=False,
56+
)
57+
op.create_index(
58+
op.f("ix_game_results_win_winner_id"),
59+
"game_results",
60+
["win_winner_id"],
61+
unique=False,
62+
)
63+
op.drop_constraint(
64+
op.f("game_results_canceler_id_fkey"),
65+
"game_results",
66+
type_="foreignkey",
67+
)
68+
op.drop_constraint(
69+
op.f("game_results_winner_id_fkey"), "game_results", type_="foreignkey",
70+
)
71+
op.drop_constraint(
72+
op.f("game_results_game_id_fkey"), "game_results", type_="foreignkey",
73+
)
74+
op.create_foreign_key(
75+
"game_results_game_id_fkey",
76+
"game_results",
77+
"games",
78+
["game_id"],
79+
["id"],
80+
initially="DEFERRED",
81+
deferrable=True,
82+
)
83+
op.create_foreign_key(
84+
"game_results_canceler_id_fkey",
85+
"game_results",
86+
"players",
87+
["canceler_id"],
88+
["id"],
89+
initially="DEFERRED",
90+
deferrable=True,
91+
)
92+
op.create_foreign_key(
93+
"game_results_winner_id_fkey",
94+
"game_results",
95+
"players",
96+
["win_winner_id"],
97+
["id"],
98+
initially="DEFERRED",
99+
deferrable=True,
100+
)
101+
op.create_index(
102+
op.f("ix_games_player1_id"), "games", ["player1_id"], unique=False,
103+
)
104+
op.create_index(
105+
op.f("ix_games_player2_id"), "games", ["player2_id"], unique=False,
106+
)
107+
op.drop_constraint(
108+
op.f("games_player1_id_fkey"), "games", type_="foreignkey",
109+
)
110+
op.drop_constraint(
111+
op.f("games_player2_id_fkey"), "games", type_="foreignkey",
112+
)
113+
op.create_foreign_key(
114+
"games_player1_id_fkey",
115+
"games",
116+
"players",
117+
["player2_id"],
118+
["id"],
119+
initially="DEFERRED",
120+
deferrable=True,
121+
)
122+
op.create_foreign_key(
123+
"games_player2_id_fkey",
124+
"games",
125+
"players",
126+
["player1_id"],
127+
["id"],
128+
initially="DEFERRED",
129+
deferrable=True,
130+
)
131+
op.create_index(
132+
op.f("ix_player_emojis_player_id"),
133+
"player_emojis",
134+
["player_id"],
135+
unique=False,
136+
)
137+
op.drop_constraint(
138+
op.f("player_emojis_player_id_fkey"),
139+
"player_emojis",
140+
type_="foreignkey",
141+
)
142+
op.create_foreign_key(
143+
"player_emojis_player_id_fkey",
144+
"player_emojis",
145+
"players",
146+
["player_id"],
147+
["id"],
148+
initially="DEFERRED",
149+
deferrable=True,
150+
)
151+
op.create_index(
152+
op.f("ix_players_game_location_game_id"),
153+
"players",
154+
["game_location_game_id"],
155+
unique=False,
156+
)
157+
op.create_index(
158+
op.f("ix_players_selected_emoji_id"),
159+
"players",
160+
["selected_emoji_id"],
161+
unique=False,
162+
)
163+
op.create_index(
164+
op.f("ix_stars_purchases_player_id"),
165+
"stars_purchases",
166+
["player_id"],
167+
unique=False,
168+
)
169+
op.drop_constraint(
170+
op.f("stars_purchases_player_id_fkey"),
171+
"stars_purchases",
172+
type_="foreignkey",
173+
)
174+
op.create_foreign_key(
175+
"stars_purchases_player_id_fkey",
176+
"stars_purchases",
177+
"players",
178+
["player_id"],
179+
["id"],
180+
initially="DEFERRED",
181+
deferrable=True,
182+
)
183+
# ### end Alembic commands ###
184+
185+
186+
def downgrade() -> None:
187+
# ### commands auto generated by Alembic - please adjust! ###
188+
op.drop_constraint(
189+
"stars_purchases_player_id_fkey", "stars_purchases", type_="foreignkey",
190+
)
191+
op.create_foreign_key(
192+
op.f("stars_purchases_player_id_fkey"),
193+
"stars_purchases",
194+
"players",
195+
["player_id"],
196+
["id"],
197+
)
198+
op.drop_index(
199+
op.f("ix_stars_purchases_player_id"), table_name="stars_purchases",
200+
)
201+
op.drop_index(op.f("ix_players_selected_emoji_id"), table_name="players")
202+
op.drop_index(
203+
op.f("ix_players_game_location_game_id"), table_name="players",
204+
)
205+
op.drop_constraint(
206+
"player_emojis_player_id_fkey", "player_emojis", type_="foreignkey",
207+
)
208+
op.create_foreign_key(
209+
op.f("player_emojis_player_id_fkey"),
210+
"player_emojis",
211+
"players",
212+
["player_id"],
213+
["id"],
214+
)
215+
op.drop_index(
216+
op.f("ix_player_emojis_player_id"), table_name="player_emojis",
217+
)
218+
op.drop_constraint("games_player2_id_fkey", "games", type_="foreignkey")
219+
op.drop_constraint("games_player1_id_fkey", "games", type_="foreignkey")
220+
op.create_foreign_key(
221+
op.f("games_player2_id_fkey"),
222+
"games",
223+
"players",
224+
["player2_id"],
225+
["id"],
226+
)
227+
op.create_foreign_key(
228+
op.f("games_player1_id_fkey"),
229+
"games",
230+
"players",
231+
["player1_id"],
232+
["id"],
233+
)
234+
op.drop_index(op.f("ix_games_player2_id"), table_name="games")
235+
op.drop_index(op.f("ix_games_player1_id"), table_name="games")
236+
op.drop_constraint(
237+
"game_results_game_id_fkey", "game_results", type_="foreignkey",
238+
)
239+
op.drop_constraint(
240+
"game_results_winner_id_fkey", "game_results", type_="foreignkey",
241+
)
242+
op.drop_constraint(
243+
"game_results_canceler_id_fkey", "game_results", type_="foreignkey",
244+
)
245+
op.create_foreign_key(
246+
op.f("game_results_game_id_fkey"),
247+
"game_results",
248+
"games",
249+
["game_id"],
250+
["id"],
251+
)
252+
op.create_foreign_key(
253+
op.f("game_results_winner_id_fkey"),
254+
"game_results",
255+
"players",
256+
["win_winner_id"],
257+
["id"],
258+
)
259+
op.create_foreign_key(
260+
op.f("game_results_canceler_id_fkey"),
261+
"game_results",
262+
"players",
263+
["canceler_id"],
264+
["id"],
265+
)
266+
op.drop_index(
267+
op.f("ix_game_results_win_winner_id"), table_name="game_results",
268+
)
269+
op.drop_index(
270+
op.f("ix_game_results_canceler_id"), table_name="game_results",
271+
)
272+
op.drop_constraint("cells_game_id_fkey", "cells", type_="foreignkey")
273+
op.drop_constraint("cells_filler_id_fkey", "cells", type_="foreignkey")
274+
op.create_foreign_key(
275+
op.f("cells_game_id_fkey"), "cells", "games", ["game_id"], ["id"],
276+
)
277+
op.create_foreign_key(
278+
op.f("cells_filler_id_fkey"), "cells", "players", ["filler_id"], ["id"],
279+
)
280+
op.drop_index(op.f("ix_cells_game_id"), table_name="cells")
281+
op.drop_index(op.f("ix_cells_filler_id"), table_name="cells")
282+
# ### end Alembic commands ###

src/ttt/infrastructure/sqlalchemy/tables.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class TablePlayerEmoji(Base):
3737
__tablename__ = "player_emojis"
3838

3939
id: Mapped[UUID] = mapped_column(primary_key=True)
40-
player_id: Mapped[int] = mapped_column(ForeignKey("players.id"))
40+
player_id: Mapped[int] = mapped_column(
41+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
42+
index=True,
43+
)
4144
emoji_str: Mapped[str] = mapped_column(CHAR(1))
4245
datetime_of_purchase: Mapped[datetime]
4346

@@ -64,7 +67,10 @@ class TableStarsPurchase(Base):
6467

6568
id: Mapped[str] = mapped_column(primary_key=True)
6669
payment_gateway_id: Mapped[str] = mapped_column(primary_key=True)
67-
player_id: Mapped[int] = mapped_column(ForeignKey("players.id"))
70+
player_id: Mapped[int] = mapped_column(
71+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
72+
index=True,
73+
)
6874
stars: Mapped[int]
6975
kopecks: Mapped[int]
7076
datetime_: Mapped[datetime]
@@ -98,12 +104,14 @@ class TablePlayer(Base):
98104
account_stars: Mapped[int] = mapped_column(server_default="0")
99105
selected_emoji_id: Mapped[UUID | None] = mapped_column(
100106
ForeignKey("player_emojis.id", deferrable=True, initially="DEFERRED"),
107+
index=True,
101108
)
102109
number_of_wins: Mapped[int]
103110
number_of_draws: Mapped[int]
104111
number_of_defeats: Mapped[int]
105112
game_location_game_id: Mapped[UUID | None] = mapped_column(
106113
ForeignKey("games.id", deferrable=True, initially="DEFERRED"),
114+
index=True,
107115
)
108116
game_location_chat_id: Mapped[int | None] = mapped_column(BigInteger())
109117

@@ -174,18 +182,23 @@ class TableGameResult(Base):
174182
__tablename__ = "game_results"
175183

176184
id: Mapped[UUID] = mapped_column(primary_key=True)
177-
game_id: Mapped[UUID] = mapped_column(ForeignKey("games.id"), unique=True)
185+
game_id: Mapped[UUID] = mapped_column(
186+
ForeignKey("games.id", deferrable=True, initially="DEFERRED"),
187+
unique=True,
188+
)
178189
type: Mapped[TableGameResultType] = mapped_column(game_result_type)
179190

180191
win_winner_id: Mapped[int | None] = mapped_column(
181192
BigInteger(),
182-
ForeignKey("players.id"),
193+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
194+
index=True,
183195
)
184196
win_new_stars: Mapped[int | None]
185197

186198
canceler_id: Mapped[int | None] = mapped_column(
187199
BigInteger(),
188-
ForeignKey("players.id"),
200+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
201+
index=True,
189202
)
190203

191204
def entity(self) -> GameResult:
@@ -243,12 +256,16 @@ class TableCell(Base):
243256
__tablename__ = "cells"
244257

245258
id: Mapped[UUID] = mapped_column(primary_key=True)
246-
game_id: Mapped[UUID] = mapped_column(ForeignKey("games.id"))
259+
game_id: Mapped[UUID] = mapped_column(
260+
ForeignKey("games.id", deferrable=True, initially="DEFERRED"),
261+
index=True,
262+
)
247263
board_position_x: Mapped[int]
248264
board_position_y: Mapped[int]
249265
filler_id: Mapped[int | None] = mapped_column(
250266
BigInteger(),
251-
ForeignKey("players.id"),
267+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
268+
index=True,
252269
)
253270

254271
def entity(self) -> Cell:
@@ -308,11 +325,13 @@ class TableGame(Base):
308325
id: Mapped[UUID] = mapped_column(primary_key=True)
309326
player1_id: Mapped[int] = mapped_column(
310327
BigInteger(),
311-
ForeignKey("players.id"),
328+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
329+
index=True,
312330
)
313331
player2_id: Mapped[int] = mapped_column(
314332
BigInteger(),
315-
ForeignKey("players.id"),
333+
ForeignKey("players.id", deferrable=True, initially="DEFERRED"),
334+
index=True,
316335
)
317336
state: Mapped[TableGameState] = mapped_column(game_state)
318337

0 commit comments

Comments
 (0)