Fix FK violations when pruning stale routes #32

Merged
TheFurya merged 2 commits from develop into main 2026-02-21 17:57:00 +01:00
Showing only changes of commit 3b63285bd1 - Show all commits

View File

@@ -1,11 +1,12 @@
"""Database upsert helpers for seed data.""" """Database upsert helpers for seed data."""
from sqlalchemy import delete, select from sqlalchemy import delete, select, update
from sqlalchemy.dialects.postgresql import insert from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from app.models.boss_battle import BossBattle from app.models.boss_battle import BossBattle
from app.models.boss_pokemon import BossPokemon from app.models.boss_pokemon import BossPokemon
from app.models.encounter import Encounter
from app.models.evolution import Evolution from app.models.evolution import Evolution
from app.models.game import Game from app.models.game import Game
from app.models.pokemon import Pokemon from app.models.pokemon import Pokemon
@@ -195,17 +196,33 @@ async def upsert_routes(
for child in route.get("children", []): for child in route.get("children", []):
seed_names.add(child["name"]) seed_names.add(child["name"])
pruned = await session.execute( # Find stale route IDs, excluding routes with user encounters
delete(Route) in_use_subq = select(Encounter.route_id).distinct().subquery()
.where( stale_route_ids_result = await session.execute(
select(Route.id).where(
Route.version_group_id == version_group_id, Route.version_group_id == version_group_id,
Route.name.not_in(seed_names), Route.name.not_in(seed_names),
Route.id.not_in(select(in_use_subq)),
) )
.returning(Route.id)
) )
pruned_count = len(pruned.all()) stale_route_ids = [row.id for row in stale_route_ids_result]
if pruned_count:
print(f" Pruned {pruned_count} stale route(s)") if stale_route_ids:
# Delete encounters referencing stale routes (no DB-level cascade)
await session.execute(
delete(RouteEncounter).where(
RouteEncounter.route_id.in_(stale_route_ids)
)
)
# Nullify boss battle references to stale routes
await session.execute(
update(BossBattle)
.where(BossBattle.after_route_id.in_(stale_route_ids))
.values(after_route_id=None)
)
# Now safe to delete the routes
await session.execute(delete(Route).where(Route.id.in_(stale_route_ids)))
print(f" Pruned {len(stale_route_ids)} stale route(s)")
await session.flush() await session.flush()