@@ -47,12 +47,18 @@ def upgrade() -> None:
4747
4848 # 1. DB-specific search indexes on roms.name and roms.fs_name.
4949 if is_mysql (bind ) or is_mariadb (bind ):
50- op .execute (
51- sa .text (
52- f"CREATE FULLTEXT INDEX { FULLTEXT_INDEX_NAME } "
53- "ON roms (name, fs_name)"
50+ # MySQL/MariaDB have no portable "IF NOT EXISTS" for FULLTEXT indexes, so
51+ # guard the create to stay idempotent if a prior run partially applied.
52+ existing_indexes = {
53+ index ["name" ] for index in sa .inspect (bind ).get_indexes ("roms" )
54+ }
55+ if FULLTEXT_INDEX_NAME not in existing_indexes :
56+ op .execute (
57+ sa .text (
58+ f"CREATE FULLTEXT INDEX { FULLTEXT_INDEX_NAME } "
59+ "ON roms (name, fs_name)"
60+ )
5461 )
55- )
5662 elif is_postgresql (bind ):
5763 # pg_trgm is a trusted extension since PostgreSQL 13, so a non-superuser
5864 # with CREATE on the database can install it.
@@ -130,7 +136,12 @@ def downgrade() -> None:
130136
131137 # 1. DB-specific search indexes.
132138 if is_mysql (bind ) or is_mariadb (bind ):
133- op .execute (sa .text (f"DROP INDEX { FULLTEXT_INDEX_NAME } ON roms" ))
139+ # MySQL has no portable "IF EXISTS" for DROP INDEX, so guard the drop.
140+ existing_indexes = {
141+ index ["name" ] for index in sa .inspect (bind ).get_indexes ("roms" )
142+ }
143+ if FULLTEXT_INDEX_NAME in existing_indexes :
144+ op .execute (sa .text (f"DROP INDEX { FULLTEXT_INDEX_NAME } ON roms" ))
134145 elif is_postgresql (bind ):
135146 # Leave the pg_trgm extension in place; other objects may depend on it.
136147 op .execute (sa .text (f"DROP INDEX IF EXISTS { PG_FS_NAME_INDEX } " ))
0 commit comments