semillero-INVIMA/backend/products_comands.py

123 lines
3.9 KiB
Python

# products_comands.py
# Uso:
# python .\products_comands.py .\Productos.csv .\comandos.txt
import csv, sys, os
TABLA = 'productos'
COLUMNAS = ['id_producto', 'nombre_comercial', 'categoria_general']
BLOQUE = 5000000
USAR_NULL = False # True => '' -> NULL
INSERT_POR_FILA = False # True => un INSERT por cada fila
def esc(s: str) -> str:
if s is None:
return "NULL" if USAR_NULL else "''"
s = str(s).strip().replace("'", "''")
if s == '':
return "NULL" if USAR_NULL else "''"
return f"'{s}'"
def es_encabezado(fila):
if not fila: return False
lowers = [c.lower().strip() for c in fila]
claves = ['id_producto', 'nombre_comercial', 'categoria_general', 'id', 'nombre', 'categoria']
return sum(any(k in c for k in claves) for c in lowers) >= 2
def leer_csv(ruta):
posibles = ['utf-8-sig', 'utf-8', 'cp1252', 'latin-1']
ultimo_error = None
for enc in posibles:
try:
with open(ruta, 'r', encoding=enc, newline='') as f:
muestra = f.read(4096); f.seek(0)
try:
dialect = csv.Sniffer().sniff(muestra, delimiters=",;\t|")
except Exception:
dialect = csv.excel_tab if '\t' in muestra else csv.excel
return list(csv.reader(f, dialect))
except UnicodeDecodeError as e:
ultimo_error = e
continue
try:
import chardet
with open(ruta, 'rb') as fb:
raw = fb.read()
enc = (chardet.detect(raw).get('encoding') or 'latin-1')
with open(ruta, 'r', encoding=enc, errors='replace', newline='') as f:
muestra = f.read(4096); f.seek(0)
try:
dialect = csv.Sniffer().sniff(muestra, delimiters=",;\t|")
except Exception:
dialect = csv.excel_tab if '\t' in muestra else csv.excel
return list(csv.reader(f, dialect))
except Exception:
pass
raise ultimo_error or UnicodeDecodeError("decode", b"", 0, 1, "No se pudo decodificar el CSV")
def nombre_salida(ruta_in, ruta_out=None):
if ruta_out: return ruta_out
base, _ = os.path.splitext(ruta_in)
return base + '_insert.txt'
def main():
if len(sys.argv) < 2:
print("Uso: python products_comands.py archivo.csv [salida.txt]", file=sys.stderr)
sys.exit(1)
ruta_csv = sys.argv[1]
ruta_txt = nombre_salida(ruta_csv, sys.argv[2] if len(sys.argv) >= 3 else None)
filas = leer_csv(ruta_csv)
if filas and es_encabezado(filas[0]):
filas = filas[1:]
vistos = set() # para detectar id_producto repetidos
duplicadas = 0
valores = []
for fila in filas:
if not fila:
continue
idp = (fila[0] if len(fila) > 0 else '').strip()
nombre = fila[1] if len(fila) > 1 else ''
categoria = fila[2] if len(fila) > 2 else ''
if idp == '':
duplicadas += 1
continue
if idp in vistos:
duplicadas += 1
continue
vistos.add(idp)
valores.append(f"({esc(idp)}, {esc(nombre)}, {esc(categoria)})")
cols = ", ".join(COLUMNAS)
lineas = []
if INSERT_POR_FILA:
for v in valores:
lineas.append(f"INSERT INTO {TABLA} ({cols}) VALUES {v};")
else:
if BLOQUE and BLOQUE > 0:
for i in range(0, len(valores), BLOQUE):
chunk = valores[i:i+BLOQUE]
lineas.append(f"INSERT INTO {TABLA} ({cols}) VALUES")
lineas.append(",\n".join(chunk) + ";")
else:
lineas.append(f"INSERT INTO {TABLA} ({cols}) VALUES")
lineas.append(",\n".join(valores) + ";")
with open(ruta_txt, 'w', encoding='utf-8') as f:
f.write("\n".join(lineas))
print(f"Listo: {ruta_txt} (omitidas por duplicado/ vacío: {duplicadas})")
if __name__ == "__main__":
main()