Я создаю приложение PyQt5, которое подключается к базе данных MySQL, используя отдельный класс, реализованный с использованием принципов ООП. Код взаимодействия с базой данных тестировался независимо, и все работало корректно: я мог добавлять, редактировать и извлекать данные.
Однако, когда я интегрировал этот код в графический интерфейс PyQt5, приложение просто закрывается. после нажатия кнопки должна получить данные из базы данных. Консоль не показывает ошибок. Графический интерфейс запускается правильно, но когда я нажимаю кнопку, программа зависает на секунду, а затем резко закрывается.
Вот код графического интерфейса:
import os
from typing import Any, Dict, List, Optional, Union
from dotenv import load_dotenv
from mysql.connector import connect, Error
from mysql.connector.connection_cext import CMySQLConnection
from mysql.connector.cursor_cext import CMySQLCursor
class Database:
def __init__(self):
load_dotenv()
try:
self.conn: Optional[CMySQLConnection] = connect(
host=os.getenv("DB_HOST"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
database=os.getenv("DB_NAME"),
)
self.cursor: CMySQLCursor = self.conn.cursor()
print("Database connection established.")
except Error as e:
raise ConnectionError(f"Failed to connect to the database: {e}")
def execute_query(self, query: str, params: Optional[tuple] = None) -> None:
try:
self.cursor.execute(query, params or ())
self.conn.commit()
except Error as e:
raise RuntimeError(f"Query execution failed: {query}. Error: {e}")
def fetch_all(self, query: str, params: Optional[tuple] = None) -> List[tuple]:
try:
self.cursor.execute(query, params or ())
return self.cursor.fetchall()
except Error as e:
raise RuntimeError(f"Failed to fetch data: {query}. Error: {e}")
def fetch_one(self, query: str, params: Optional[tuple] = None) -> Optional[tuple]:
try:
self.cursor.execute(query, params or ())
return self.cursor.fetchone()
except Error as e:
raise RuntimeError(f"Failed to fetch data: {query}. Error: {e}")
def close_connection(self) -> None:
if self.cursor:
self.cursor.close()
if self.conn:
self.conn.close()
print("Database connection closed.")
def __del__(self):
try:
self.close_connection()
except Exception as e:
print(f"Error during cleanup: {e}")
class Client(Database):
def create_table(self) -> None:
self.execute_query("""
CREATE TABLE IF NOT EXISTS clients (
client_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
phone VARCHAR(20),
email VARCHAR(100)
)
""")
def add_client(self, name: str, phone: str, email: str) -> None:
self.execute_query(
"INSERT INTO clients (name, phone, email) VALUES (%s, %s, %s)",
(name, phone, email),
)
def update_client(self, client_id: int, **kwargs: str) -> None:
update_query = "UPDATE clients SET "
update_values = []
for key, value in kwargs.items():
update_query += f"{key} = %s, "
update_values.append(value)
update_query = update_query.rstrip(", ") + " WHERE client_id = %s"
update_values.append(client_id)
self.execute_query(update_query, tuple(update_values))
def get_client(self, client_id: int) -> Optional[Dict[str, Any]]:
try:
client = self.fetch_one(
"SELECT * FROM clients WHERE client_id = %s", (client_id,)
)
return dict(zip(["client_id", "name", "phone", "email"], client)) if client else None
except Exception as e:
print(f"Error fetching client: {e}")
return None
def get_all_clients(self) -> List[Dict[str, Any]]:
clients = self.fetch_all("SELECT * FROM clients")
return [dict(zip(["client_id", "name", "phone", "email"], client)) for client in clients]
def delete_client(self, client_id: int) -> None:
self.execute_query(
"DELETE FROM clients WHERE client_id = %s", (client_id,)
)
Ожидаемое поведение: после нажатия кнопки метка в окне должна отображать имя клиента из базы данных или сообщение о том, что клиент не найден.
Что пробовал:
Протестировал код взаимодействия с базой данных самостоятельно — работает отлично.
Добавлен блок try-кроме в setValue для обнаружения любых ошибок, но графический интерфейс все равно закрывается. без отображения каких-либо сообщений.
Убедился, что переменные среды для подключения к базе данных настроены правильно.
Я делаю что-то не так в том, как я использую PyQt5 или подключаюсь к базе данных в контексте приложения с графическим интерфейсом? Что могло привести к внезапному закрытию программы без каких-либо ошибок в консоли?
Я создаю приложение PyQt5, которое подключается к базе данных MySQL, используя отдельный класс, реализованный с использованием принципов ООП. Код взаимодействия с базой данных тестировался независимо, и все работало корректно: я мог добавлять, редактировать и извлекать данные. Однако, когда я интегрировал этот код в графический интерфейс PyQt5, приложение просто закрывается. после нажатия кнопки должна получить данные из базы данных. Консоль не показывает ошибок. Графический интерфейс запускается правильно, но когда я нажимаю кнопку, программа зависает на секунду, а затем резко закрывается. Вот код графического интерфейса: [code]import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout from utils import Client
class MyWindow(QWidget): def __init__(self): super().__init__() self.initUI()
def setValue(self): try: client = Client() client_data = client.get_client(8) if client_data: self.label.setText(client_data["name"]) else: self.label.setText("Client not found") except Exception as e: self.label.setText(f"Error: {e}") print(f"Error: {e}") finally: del client
def clearValue(self): self.label.setText('0')
if __name__ == '__main__': app = QApplication(sys.argv) window = MyWindow() sys.exit(app.exec_()) [/code] И код взаимодействия с базой данных: [code]import os from typing import Any, Dict, List, Optional, Union
from dotenv import load_dotenv from mysql.connector import connect, Error from mysql.connector.connection_cext import CMySQLConnection from mysql.connector.cursor_cext import CMySQLCursor
class Database: def __init__(self): load_dotenv() try: self.conn: Optional[CMySQLConnection] = connect( host=os.getenv("DB_HOST"), user=os.getenv("DB_USER"), password=os.getenv("DB_PASSWORD"), database=os.getenv("DB_NAME"), ) self.cursor: CMySQLCursor = self.conn.cursor() print("Database connection established.") except Error as e: raise ConnectionError(f"Failed to connect to the database: {e}")
def get_all_clients(self) -> List[Dict[str, Any]]: clients = self.fetch_all("SELECT * FROM clients") return [dict(zip(["client_id", "name", "phone", "email"], client)) for client in clients]
def delete_client(self, client_id: int) -> None: self.execute_query( "DELETE FROM clients WHERE client_id = %s", (client_id,) ) [/code] Ожидаемое поведение: после нажатия кнопки метка в окне должна отображать имя клиента из базы данных или сообщение о том, что клиент не найден. Что пробовал: [list] [*]Протестировал код взаимодействия с базой данных самостоятельно — работает отлично. [*] Добавлен блок try-кроме в setValue для обнаружения любых ошибок, но графический интерфейс все равно закрывается. без отображения каких-либо сообщений. [*]Убедился, что переменные среды для подключения к базе данных настроены правильно. [/list] Я делаю что-то не так в том, как я использую PyQt5 или подключаюсь к базе данных в контексте приложения с графическим интерфейсом? Что могло привести к внезапному закрытию программы без каких-либо ошибок в консоли?