stvnnnnnn commited on
Commit
13233ee
·
verified ·
1 Parent(s): 689a2c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -8
app.py CHANGED
@@ -154,19 +154,21 @@ def import_sql_dump_to_sqlite(db_path: str, sql_text: str) -> None:
154
  """
155
  Convertidor avanzado MySQL → SQLite.
156
  Limpia, reordena y ejecuta el schema de forma segura en SQLite.
 
157
  """
158
 
159
  # ======================================================
160
  # 1) Limpieza inicial del dump
161
  # ======================================================
162
 
163
- # Remover comentarios estilo MySQL
164
  sql_text = re.sub(r"/\*![\s\S]*?\*/;", "", sql_text)
165
  sql_text = re.sub(r"/\*[\s\S]*?\*/", "", sql_text)
166
  sql_text = re.sub(r"--.*?\n", "", sql_text)
167
 
168
- # Remover `DELIMITER` (no existe en SQLite)
169
  sql_text = re.sub(r"DELIMITER\s+.+", "", sql_text)
 
170
 
171
  # Quitar ENGINE, ROW_FORMAT, AUTO_INCREMENT
172
  sql_text = re.sub(r"ENGINE=\w+", "", sql_text)
@@ -178,7 +180,11 @@ def import_sql_dump_to_sqlite(db_path: str, sql_text: str) -> None:
178
  sql_text = re.sub(r"CHARACTER SET \w+", "", sql_text)
179
  sql_text = re.sub(r"COLLATE \w+", "", sql_text)
180
 
181
- # Reemplazar backticks por comillas
 
 
 
 
182
  sql_text = sql_text.replace("`", "")
183
 
184
  # ======================================================
@@ -279,8 +285,21 @@ def import_sql_dump_to_sqlite(db_path: str, sql_text: str) -> None:
279
 
280
  cur.execute("PRAGMA foreign_keys = ON;")
281
  conn.commit()
 
 
 
 
 
 
282
  conn.close()
283
 
 
 
 
 
 
 
 
284
 
285
  def extract_table_name(create_stmt: str) -> str:
286
  m = re.search(r"CREATE TABLE\s+(\w+)", create_stmt, re.IGNORECASE)
@@ -754,7 +773,7 @@ async def upload_database(db_file: UploadFile = File(...)):
754
  Subida universal de BD.
755
  El usuario puede subir:
756
  - .sqlite / .db → se usa tal cual
757
- - .sql → dump MySQL/PostgreSQL/SQLite → se importa a SQLite
758
  - .csv → se crea una BD SQLite y una tabla
759
  - .zip → puede contener .sqlite/.db, .sql o .csv (se detecta automáticamente)
760
  """
@@ -782,8 +801,28 @@ async def upload_database(db_file: UploadFile = File(...)):
782
  conn_id = create_empty_sqlite_db(label=filename)
783
  db_path = DB_REGISTRY[conn_id]["db_path"]
784
  sql_text = contents.decode("utf-8", errors="ignore")
785
- import_sql_dump_to_sqlite(db_path, sql_text)
786
- note = "SQL dump imported into SQLite (best effort)."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
 
788
  # Caso 3: CSV simple
789
  elif fname_lower.endswith(".csv"):
@@ -832,8 +871,27 @@ async def upload_database(db_file: UploadFile = File(...)):
832
  parts.append(f.read().decode("utf-8", errors="ignore"))
833
  sql_text = "\n\n".join(parts)
834
 
835
- import_sql_dump_to_sqlite(db_path, sql_text)
836
- note = "SQL dump(s) from ZIP imported into SQLite."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
837
 
838
  # 4.3: solo CSVs
839
  elif csv_names:
 
154
  """
155
  Convertidor avanzado MySQL → SQLite.
156
  Limpia, reordena y ejecuta el schema de forma segura en SQLite.
157
+ Si al final no se crea ninguna tabla, lanza ValueError.
158
  """
159
 
160
  # ======================================================
161
  # 1) Limpieza inicial del dump
162
  # ======================================================
163
 
164
+ # Remover comentarios estilo MySQL/PostgreSQL
165
  sql_text = re.sub(r"/\*![\s\S]*?\*/;", "", sql_text)
166
  sql_text = re.sub(r"/\*[\s\S]*?\*/", "", sql_text)
167
  sql_text = re.sub(r"--.*?\n", "", sql_text)
168
 
169
+ # Remover DELIMITER y statements SET típicos
170
  sql_text = re.sub(r"DELIMITER\s+.+", "", sql_text)
171
+ sql_text = re.sub(r"SET\s+[^;]+;", "", sql_text)
172
 
173
  # Quitar ENGINE, ROW_FORMAT, AUTO_INCREMENT
174
  sql_text = re.sub(r"ENGINE=\w+", "", sql_text)
 
180
  sql_text = re.sub(r"CHARACTER SET \w+", "", sql_text)
181
  sql_text = re.sub(r"COLLATE \w+", "", sql_text)
182
 
183
+ # Quitar dominios y tipos personalizados (PostgreSQL)
184
+ sql_text = re.sub(r"CREATE\s+DOMAIN[\s\S]+?;", "", sql_text, flags=re.IGNORECASE)
185
+ sql_text = re.sub(r"CREATE\s+TYPE[\s\S]+?;", "", sql_text, flags=re.IGNORECASE)
186
+
187
+ # Reemplazar backticks por nada (MySQL → SQLite)
188
  sql_text = sql_text.replace("`", "")
189
 
190
  # ======================================================
 
285
 
286
  cur.execute("PRAGMA foreign_keys = ON;")
287
  conn.commit()
288
+
289
+ # ======================================================
290
+ # 6) Validar que realmente se crearon tablas
291
+ # ======================================================
292
+ cur.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table';")
293
+ n_tables = cur.fetchone()[0]
294
  conn.close()
295
 
296
+ if n_tables == 0:
297
+ raise ValueError(
298
+ "No se creó ninguna tabla desde el dump SQL. "
299
+ "Probablemente es un dump de otro motor (por ejemplo PostgreSQL) "
300
+ "o usa sintaxis no compatible con SQLite."
301
+ )
302
+
303
 
304
  def extract_table_name(create_stmt: str) -> str:
305
  m = re.search(r"CREATE TABLE\s+(\w+)", create_stmt, re.IGNORECASE)
 
773
  Subida universal de BD.
774
  El usuario puede subir:
775
  - .sqlite / .db → se usa tal cual
776
+ - .sql → dump MySQL/SQLite (best effort convertido a SQLite)
777
  - .csv → se crea una BD SQLite y una tabla
778
  - .zip → puede contener .sqlite/.db, .sql o .csv (se detecta automáticamente)
779
  """
 
801
  conn_id = create_empty_sqlite_db(label=filename)
802
  db_path = DB_REGISTRY[conn_id]["db_path"]
803
  sql_text = contents.decode("utf-8", errors="ignore")
804
+
805
+ try:
806
+ import_sql_dump_to_sqlite(db_path, sql_text)
807
+ note = "SQL dump imported into SQLite (best effort)."
808
+ except Exception as e:
809
+ # Limpiar registro porque la BD quedó inútil
810
+ try:
811
+ if os.path.exists(db_path):
812
+ os.remove(db_path)
813
+ except Exception:
814
+ pass
815
+ DB_REGISTRY.pop(conn_id, None)
816
+
817
+ raise HTTPException(
818
+ status_code=400,
819
+ detail=(
820
+ "No se pudo convertir este archivo .sql a una base de datos SQLite utilizable. "
821
+ "Es probable que sea un dump de otro motor (por ejemplo PostgreSQL) "
822
+ "o que contenga sintaxis avanzada no compatible con SQLite.\n"
823
+ f"Detalle técnico: {e}"
824
+ ),
825
+ )
826
 
827
  # Caso 3: CSV simple
828
  elif fname_lower.endswith(".csv"):
 
871
  parts.append(f.read().decode("utf-8", errors="ignore"))
872
  sql_text = "\n\n".join(parts)
873
 
874
+ try:
875
+ import_sql_dump_to_sqlite(db_path, sql_text)
876
+ note = "SQL dump(s) from ZIP imported into SQLite."
877
+ except Exception as e:
878
+ try:
879
+ if os.path.exists(db_path):
880
+ os.remove(db_path)
881
+ except Exception:
882
+ pass
883
+ DB_REGISTRY.pop(conn_id, None)
884
+
885
+ raise HTTPException(
886
+ status_code=400,
887
+ detail=(
888
+ "No se pudo convertir los archivos .sql dentro del ZIP "
889
+ "a una base de datos SQLite utilizable. "
890
+ "Es probable que sean dumps de otro motor (por ejemplo PostgreSQL) "
891
+ "o que contengan sintaxis avanzada no compatible con SQLite.\n"
892
+ f"Detalle técnico: {e}"
893
+ ),
894
+ )
895
 
896
  # 4.3: solo CSVs
897
  elif csv_names: