CoolFace
Apppublic

douglasribeiro/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
app.py161 linesDownload Raw Back to root
1import os2import re3import shutil4import sqlite35import pandas as pd6import gradio as gr7 8DB_PATH = "loja.db"9EXPORT_DIR = "exports"10 11 12def _connect():13    return sqlite3.connect(DB_PATH, check_same_thread=False)14 15 16def _looks_like_select(sql: str) -> bool:17    s = (sql or "").strip().lower()18    return s.startswith(("select", "with", "pragma", "explain"))19 20 21def _safe_filename(name: str) -> str:22    name = (name or "").strip()23    if not name:24        name = "resultado"25    # remove caracteres ruins e espaços excessivos26    name = re.sub(r"[^\w\-\.]+", "_", name, flags=re.UNICODE)27    name = name.strip("._-")28    return name or "resultado"29 30 31def _save_df_to_csv(df: pd.DataFrame, filename_base: str) -> str:32    os.makedirs(EXPORT_DIR, exist_ok=True)33    base = _safe_filename(filename_base)34    csv_path = os.path.join(EXPORT_DIR, f"{base}.csv")35    df.to_csv(csv_path, index=False, encoding="utf-8-sig")  # BOM ajuda no Excel36    return csv_path37 38 39def executar_sql(sql: str, salvar_csv: bool, nome_csv: str):40    sql = (sql or "").strip()41    if not sql:42        return "⚠️ Cole um comando SQL.", None, None43 44    try:45        con = _connect()46        cur = con.cursor()47 48        if _looks_like_select(sql):49            df = pd.read_sql_query(sql, con)50            con.close()51 52            csv_file = None53            if salvar_csv:54                if df is None or df.empty:55                    # Ainda assim você pode preferir salvar vazio; aqui eu aviso e não gero arquivo.56                    return "⚠️ Consulta executada, mas não retornou linhas (CSV não gerado).", df, None57                csv_file = _save_df_to_csv(df, nome_csv)58 59            msg = "✅ Consulta executada com sucesso."60            if csv_file:61                msg += f" CSV gerado em: {csv_file}"62            return msg, df, csv_file63 64        # Para comandos não-SELECT (DDL/DML), aceita múltiplas instruções com ;65        cur.executescript(sql)66        con.commit()67        con.close()68        return "✅ Comando executado e commit realizado.", None, None69 70    except Exception as e:71        return f"❌ Erro ao executar SQL:\n{e}", None, None72 73 74def reset_db():75    try:76        if os.path.exists(DB_PATH):77            os.remove(DB_PATH)78        # recria vazio (arquivo nasce ao conectar)79        con = _connect()80        con.close()81        return "✅ Banco resetado. Um novo 'loja.db' vazio foi criado."82    except Exception as e:83        return f"❌ Erro ao resetar DB: {e}"84 85 86def upload_db(db_file):87    if db_file is None:88        return "⚠️ Envie um arquivo .db primeiro."89    try:90        shutil.copy(db_file, DB_PATH)91        return f"✅ Banco carregado com sucesso: {DB_PATH}"92    except Exception as e:93        return f"❌ Erro ao carregar DB: {e}"94 95 96def download_db():97    if not os.path.exists(DB_PATH):98        # cria se ainda não existir99        con = _connect()100        con.close()101    return DB_PATH102 103 104with gr.Blocks(title="SQLite — Execução de SQL (loja.db)") as demo:105    gr.Markdown(106        """107# SQLite (loja.db) — Interface Gradio108Cole seus comandos SQL e execute direto no arquivo `loja.db`.109 110**Dica:** Para múltiplos comandos (ex.: vários CREATE/INSERT), separe por `;`.111 112✅ **Novo:** marque *Salvar resultado em CSV* para exportar o resultado de consultas `SELECT`.113"""114    )115 116    with gr.Tab("Executar SQL"):117        sql_in = gr.Textbox(118            label="Comando SQL",119            placeholder="Ex.: CREATE TABLE ...;  ou  SELECT * FROM ...;",120            lines=10,121        )122 123        with gr.Row():124            salvar_csv = gr.Checkbox(label="Salvar resultado em CSV (apenas SELECT)", value=False)125            nome_csv = gr.Textbox(126                label="Nome do CSV (sem extensão)",127                placeholder="Ex.: clientes_ativos",128                value="resultado_query",129            )130 131        run_btn = gr.Button("Executar")132        status = gr.Textbox(label="Status", lines=3)133        tabela = gr.Dataframe(label="Resultado (se houver)", interactive=False)134 135        gr.Markdown("### Download do resultado (CSV)")136        csv_file = gr.File(label="Baixar CSV gerado")137 138        run_btn.click(139            executar_sql,140            inputs=[sql_in, salvar_csv, nome_csv],141            outputs=[status, tabela, csv_file],142        )143 144    with gr.Tab("Banco de Dados (Upload/Download/Reset)"):145        gr.Markdown("### Upload de um banco existente (.db)")146        up = gr.File(label="Envie um arquivo .db", file_types=[".db"])147        up_btn = gr.Button("Carregar este DB para o app")148        up_status = gr.Textbox(label="Status", lines=2)149        up_btn.click(upload_db, inputs=up, outputs=up_status)150 151        gr.Markdown("### Download do banco atual")152        dl_btn = gr.Button("Gerar arquivo para download")153        dl_file = gr.File(label="Baixar loja.db")154        dl_btn.click(download_db, inputs=None, outputs=dl_file)155 156        gr.Markdown("### Reset (apaga e recria um loja.db vazio)")157        reset_btn = gr.Button("Resetar DB", variant="stop")158        reset_status = gr.Textbox(label="Status", lines=2)159        reset_btn.click(reset_db, inputs=None, outputs=reset_status)160 161demo.launch()