113 lines
4.8 KiB
Python
113 lines
4.8 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk, messagebox
|
|
import threading
|
|
import mysql.connector
|
|
from mysql.connector import Error
|
|
|
|
class SQLQueryExecutor:
|
|
def __init__(self, parent):
|
|
"""
|
|
Clase que permite ejecutar consultas SQL en una base de datos MySQL.
|
|
|
|
Args:
|
|
parent (tk.Frame): Frame donde se colocarán los widgets de la interfaz gráfica.
|
|
"""
|
|
self.parent = parent
|
|
|
|
# Frame para ingresar los datos de conexión a la base de datos
|
|
self.db_info_frame = tk.Frame(self.parent)
|
|
self.db_info_frame.pack(pady=10, padx=10, fill="x")
|
|
|
|
tk.Label(self.db_info_frame, text="Host:").grid(row=0, column=0, sticky="w")
|
|
self.host_entry = tk.Entry(self.db_info_frame)
|
|
self.host_entry.insert(0, "localhost") # Valor por defecto
|
|
self.host_entry.grid(row=0, column=1)
|
|
|
|
tk.Label(self.db_info_frame, text="Usuario:").grid(row=1, column=0, sticky="w")
|
|
self.user_entry = tk.Entry(self.db_info_frame)
|
|
self.user_entry.insert(0, "root") # Usuario por defecto
|
|
self.user_entry.grid(row=1, column=1)
|
|
|
|
tk.Label(self.db_info_frame, text="Contraseña:").grid(row=2, column=0, sticky="w")
|
|
self.password_entry = tk.Entry(self.db_info_frame, show="*") # Campo oculto
|
|
self.password_entry.grid(row=2, column=1)
|
|
|
|
tk.Label(self.db_info_frame, text="Base de datos:").grid(row=3, column=0, sticky="w")
|
|
self.database_entry = tk.Entry(self.db_info_frame)
|
|
self.database_entry.grid(row=3, column=1)
|
|
|
|
# Botón para conectar a la base de datos
|
|
self.connect_button = tk.Button(self.db_info_frame, text="Conectar", command=self.connect_to_database)
|
|
self.connect_button.grid(row=4, column=0, columnspan=2, pady=5)
|
|
|
|
# Área para escribir la consulta SQL
|
|
self.query_frame = tk.Frame(self.parent)
|
|
self.query_frame.pack(pady=10, padx=10, fill="both", expand=True)
|
|
|
|
tk.Label(self.query_frame, text="Consulta SQL:").pack(anchor="w")
|
|
self.query_text = tk.Text(self.query_frame, height=10)
|
|
self.query_text.pack(fill="both", expand=True)
|
|
|
|
# Botón para ejecutar la consulta
|
|
self.execute_button = tk.Button(self.query_frame, text="Ejecutar", command=self.execute_query)
|
|
self.execute_button.pack(pady=5)
|
|
|
|
# Área para mostrar los resultados
|
|
self.result_frame = tk.Frame(self.parent)
|
|
self.result_frame.pack(pady=10, padx=10, fill="both", expand=True)
|
|
|
|
tk.Label(self.result_frame, text="Resultados:").pack(anchor="w")
|
|
self.result_text = tk.Text(self.result_frame, height=10, state="disabled")
|
|
self.result_text.pack(fill="both", expand=True)
|
|
|
|
def connect_to_database(self):
|
|
"""Conecta a la base de datos MySQL utilizando los datos ingresados por el usuario."""
|
|
self.host = self.host_entry.get()
|
|
self.user = self.user_entry.get()
|
|
self.password = self.password_entry.get()
|
|
self.database = self.database_entry.get()
|
|
|
|
try:
|
|
self.connection = mysql.connector.connect(
|
|
host=self.host,
|
|
user=self.user,
|
|
password=self.password,
|
|
database=self.database
|
|
)
|
|
if self.connection.is_connected():
|
|
messagebox.showinfo("Conexión Exitosa", "Conectado a la base de datos")
|
|
except Error as e:
|
|
messagebox.showerror("Error de Conexión", str(e))
|
|
|
|
def execute_query(self):
|
|
"""Ejecuta la consulta SQL en un hilo separado para evitar bloquear la interfaz."""
|
|
query = self.query_text.get("1.0", tk.END).strip()
|
|
if not query:
|
|
messagebox.showwarning("Consulta Vacía", "Por favor, ingrese una consulta SQL.")
|
|
return
|
|
|
|
threading.Thread(target=self.run_query, args=(query,), daemon=True).start()
|
|
|
|
def run_query(self, query):
|
|
"""Ejecuta la consulta en la base de datos y muestra los resultados."""
|
|
try:
|
|
cursor = self.connection.cursor()
|
|
cursor.execute(query)
|
|
|
|
if query.strip().lower().startswith("select"):
|
|
rows = cursor.fetchall()
|
|
column_names = [desc[0] for desc in cursor.description]
|
|
|
|
# Mostrar los resultados
|
|
self.result_text.config(state="normal")
|
|
self.result_text.delete("1.0", tk.END)
|
|
self.result_text.insert(tk.END, "\t".join(column_names) + "\n")
|
|
for row in rows:
|
|
self.result_text.insert(tk.END, "\t".join(map(str, row)) + "\n")
|
|
self.result_text.config(state="disabled")
|
|
else:
|
|
self.connection.commit()
|
|
messagebox.showinfo("Éxito", "Consulta ejecutada correctamente.")
|
|
except Error as e:
|
|
messagebox.showerror("Error de Consulta", str(e))
|