Skip to content

Commit 309d037

Browse files
committed
🐛 fix MySQL to SQLite transpilation and improve error handling
1 parent 7f7ffbf commit 309d037

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/mysql_to_sqlite3/transporter.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,8 @@ def _translate_type_from_mysql_to_sqlite(
306306
return sqlglot_type
307307
return "TEXT"
308308

309-
@staticmethod
310-
def _transpile_mysql_expr_to_sqlite(expr_sql: str) -> t.Optional[str]:
309+
@classmethod
310+
def _transpile_mysql_expr_to_sqlite(cls, expr_sql: str) -> t.Optional[str]:
311311
"""Transpile a MySQL scalar expression to SQLite using sqlglot.
312312
313313
Returns the SQLite SQL string on success, or None on failure.
@@ -316,7 +316,12 @@ def _transpile_mysql_expr_to_sqlite(expr_sql: str) -> t.Optional[str]:
316316
try:
317317
tree: Expression = parse_one(cleaned, read="mysql")
318318
return tree.sql(dialect="sqlite")
319-
except (ParseError, ValueError, Exception): # pylint: disable=W0718
319+
except (ParseError, ValueError):
320+
return None
321+
except Exception: # pragma: no cover
322+
logging.getLogger(cls.__name__ if hasattr(cls, "__name__") else "MySQLtoSQLite").debug(
323+
"sqlglot failed to transpile expr: %r", expr_sql
324+
)
320325
return None
321326

322327
@staticmethod
@@ -785,8 +790,9 @@ def _build_create_table_sql(self, table_name: str) -> str:
785790
unique_index_name = self._get_unique_index_name(proposed_index_name)
786791
else:
787792
unique_index_name = proposed_index_name
788-
indices += """CREATE {unique} INDEX IF NOT EXISTS {name} ON {table} ({columns});""".format(
789-
unique="UNIQUE" if index["unique"] in {1, "1"} else "",
793+
unique_kw = "UNIQUE " if index["unique"] in {1, "1"} else ""
794+
indices += """CREATE {unique}INDEX IF NOT EXISTS {name} ON {table} ({columns});""".format(
795+
unique=unique_kw,
790796
name=self._quote_sqlite_identifier(unique_index_name),
791797
table=self._quote_sqlite_identifier(table_name),
792798
columns=", ".join(
@@ -848,8 +854,8 @@ def _build_create_table_sql(self, table_name: str) -> str:
848854
if isinstance(foreign_key["ref_column"], (bytes, bytearray))
849855
else str(foreign_key["ref_column"]) # type: ignore[index]
850856
)
851-
on_update = foreign_key["on_update"] # type: ignore[index]
852-
on_delete = foreign_key["on_delete"] # type: ignore[index]
857+
on_update = str(foreign_key["on_update"] or "NO ACTION").upper() # type: ignore[index]
858+
on_delete = str(foreign_key["on_delete"] or "NO ACTION").upper() # type: ignore[index]
853859
sql += (
854860
f",\n\tFOREIGN KEY({col}) REFERENCES {ref_table} ({ref_col}) "
855861
f"ON UPDATE {on_update} "
@@ -1159,13 +1165,15 @@ def _coerce_row(row: t.Any) -> t.Tuple[str, str]:
11591165
# get the size of the data
11601166
if self._limit_rows > 0:
11611167
# limit to the requested number of rows
1168+
safe_table = self._escape_mysql_backticks(table_name)
11621169
self._mysql_cur_dict.execute(
11631170
"SELECT COUNT(*) AS `total_records` "
1164-
f"FROM (SELECT * FROM `{table_name}` LIMIT {self._limit_rows}) AS `table`"
1171+
f"FROM (SELECT * FROM `{safe_table}` LIMIT {self._limit_rows}) AS `table`"
11651172
)
11661173
else:
11671174
# get all rows
1168-
self._mysql_cur_dict.execute(f"SELECT COUNT(*) AS `total_records` FROM `{table_name}`")
1175+
safe_table = self._escape_mysql_backticks(table_name)
1176+
self._mysql_cur_dict.execute(f"SELECT COUNT(*) AS `total_records` FROM `{safe_table}`")
11691177

11701178
total_records: t.Optional[t.Dict[str, RowItemType]] = self._mysql_cur_dict.fetchone()
11711179
if total_records is not None:
@@ -1176,9 +1184,10 @@ def _coerce_row(row: t.Any) -> t.Tuple[str, str]:
11761184
# only continue if there is anything to transfer
11771185
if total_records_count > 0:
11781186
# populate it
1187+
safe_table = self._escape_mysql_backticks(table_name)
11791188
self._mysql_cur.execute(
11801189
"SELECT * FROM `{table_name}` {limit}".format(
1181-
table_name=table_name,
1190+
table_name=safe_table,
11821191
limit=f"LIMIT {self._limit_rows}" if self._limit_rows > 0 else "",
11831192
)
11841193
)

0 commit comments

Comments
 (0)