@@ -146,6 +146,11 @@ def __init__(self, **kwargs: Unpack[MySQLtoSQLiteParams]) -> None:
146146
147147 self ._sqlite_json1_extension_enabled = not self ._json_as_text and self ._check_sqlite_json1_extension_enabled ()
148148
149+ # Track seen SQLite index names to generate unique names when prefixing is disabled
150+ self ._seen_sqlite_index_names : t .Set [str ] = set ()
151+ # Counter for duplicate index names to assign numeric suffixes (name_2, name_3, ...)
152+ self ._sqlite_index_name_counters : t .Dict [str , int ] = {}
153+
149154 try :
150155 _mysql_connection = mysql .connector .connect (
151156 user = self ._mysql_user ,
@@ -409,6 +414,33 @@ def _check_sqlite_json1_extension_enabled(self) -> bool:
409414 except sqlite3 .Error :
410415 return False
411416
417+ def _get_unique_index_name (self , base_name : str ) -> str :
418+ """Return a unique SQLite index name based on base_name.
419+
420+ If base_name has not been used yet, it is returned as-is and recorded. If it has been
421+ used, a numeric suffix is appended starting from 2 (e.g., name_2, name_3, ...), and the
422+ chosen name is recorded as used. This behavior is only intended for cases where index
423+ prefixing is not enabled and SQLite requires global uniqueness for index names.
424+ """
425+ if base_name not in self ._seen_sqlite_index_names :
426+ self ._seen_sqlite_index_names .add (base_name )
427+ return base_name
428+ # Base name already seen — assign next available counter
429+ next_num = self ._sqlite_index_name_counters .get (base_name , 2 )
430+ candidate = f"{ base_name } _{ next_num } "
431+ while candidate in self ._seen_sqlite_index_names :
432+ next_num += 1
433+ candidate = f"{ base_name } _{ next_num } "
434+ # Record chosen candidate and bump counter for the base name
435+ self ._seen_sqlite_index_names .add (candidate )
436+ self ._sqlite_index_name_counters [base_name ] = next_num + 1
437+ self ._logger .info (
438+ 'Index "%s" renamed to "%s" to ensure uniqueness across the SQLite database.' ,
439+ base_name ,
440+ candidate ,
441+ )
442+ return candidate
443+
412444 def _build_create_table_sql (self , table_name : str ) -> str :
413445 sql : str = f'CREATE TABLE IF NOT EXISTS "{ table_name } " ('
414446 primary : str = ""
@@ -523,13 +555,20 @@ def _build_create_table_sql(self, table_name: str) -> str:
523555 columns = ", " .join (f'"{ column } "' for column in columns .split ("," ))
524556 )
525557 else :
558+ # Determine the SQLite index name, considering table name collisions and prefix option
559+ proposed_index_name = (
560+ f"{ table_name } _{ index_name } "
561+ if (table_collisions > 0 or self ._prefix_indices )
562+ else index_name
563+ )
564+ # Ensure index name is unique across the whole SQLite database when prefixing is disabled
565+ if not self ._prefix_indices :
566+ unique_index_name = self ._get_unique_index_name (proposed_index_name )
567+ else :
568+ unique_index_name = proposed_index_name
526569 indices += """CREATE {unique} INDEX IF NOT EXISTS "{name}" ON "{table}" ({columns});""" .format (
527570 unique = "UNIQUE" if index ["unique" ] in {1 , "1" } else "" ,
528- name = (
529- f"{ table_name } _{ index_name } "
530- if (table_collisions > 0 or self ._prefix_indices )
531- else index_name
532- ),
571+ name = unique_index_name ,
533572 table = table_name ,
534573 columns = ", " .join (f'"{ column } "' for column in columns .split ("," )),
535574 )
0 commit comments