@@ -324,6 +324,20 @@ def _transpile_mysql_expr_to_sqlite(cls, expr_sql: str) -> t.Optional[str]:
324324 )
325325 return None
326326
327+ @classmethod
328+ def _normalize_literal_with_sqlglot (cls , expr_sql : str ) -> t .Optional [str ]:
329+ """Normalize a MySQL literal using sqlglot, returning SQLite SQL if literal-like."""
330+ cleaned : str = expr_sql .strip ().rstrip (";" )
331+ try :
332+ node : Expression = parse_one (cleaned , read = "mysql" )
333+ except (ParseError , ValueError ):
334+ return None
335+ if isinstance (node , exp .Literal ):
336+ return node .sql (dialect = "sqlite" )
337+ if isinstance (node , exp .Paren ) and isinstance (node .this , exp .Literal ):
338+ return node .this .sql (dialect = "sqlite" )
339+ return None
340+
327341 @staticmethod
328342 def _quote_sqlite_identifier (name : t .Union [str , bytes , bytearray ]) -> str :
329343 """Safely quote an identifier for SQLite using sqlglot.
@@ -569,7 +583,15 @@ def _translate_default_from_mysql_to_sqlite(
569583 # Allow simple arithmetic constant expressions composed of numbers and + - * /
570584 if re .match (r"^[\d\.\s\+\-\*/\(\)]+$" , norm ) and any (ch .isdigit () for ch in norm ):
571585 return f"DEFAULT { norm } "
572- # Robustly escape single quotes for plain string defaults
586+ stripped_default = column_default .strip ()
587+ if stripped_default .startswith ("'" ) or (
588+ stripped_default .startswith ("(" ) and stripped_default .endswith (")" )
589+ ):
590+ normalized_literal : t .Optional [str ] = cls ._normalize_literal_with_sqlglot (column_default )
591+ if normalized_literal is not None :
592+ return f"DEFAULT { normalized_literal } "
593+
594+ # Fallback: robustly escape single quotes for plain string defaults
573595 _escaped = column_default .replace ("\\ '" , "'" )
574596 _escaped = _escaped .replace ("'" , "''" )
575597 return f"DEFAULT '{ _escaped } '"
0 commit comments