CS Project: Database Management UI
with Tkinter
Overview
This project involves creating a graphical user interface (GUI) to interact with a MySQL
database using Python’s Tkinter and mysql.connector.
The application provides functionalities to:
- View and interact with data from different tables in the database.
- Add new records to the selected table.
- Fetch and display data dynamically based on the table selection.
Features:
1. Table Selection: Users can select a table from a dropdown menu.
2. Display Table Data: A treeview displays the data from the selected table.
3. Add New Record: Users can fill out a form to add new records to the selected table.
4. Validation and Error Handling: Ensures that all fields are filled before submission and
handles database errors gracefully.
Detailed Explanation of the Code
1. Database Connection
The create_connection() function establishes a connection to the MySQL database.
def create_connection() -> MySQLConnection:
"""Create a connection to the MySQL database."""
try:
connection = connect(
host="localhost",
user="root",
passwd="1977",
database="usdms"
)
return connection
except Exception as e:
messagebox.showerror("Database Error", f"Error connecting to database: {e}")
raise
2. Fetching Data from the Database
The fetch_data() function retrieves data from the database based on a provided query.
def fetch_data(connection: MySQLConnection, query: str, params: Optional[tuple] = None) -
> List[Dict]:
"""Fetch data from the database."""
cursor = None
try:
cursor = connection.cursor(dictionary=True)
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
return cursor.fetchall()
except Exception as e:
messagebox.showerror("Error", f"Error fetching data: {e}")
return []
finally:
if cursor:
cursor.close()
3. Displaying Data in the UI
The fetch_and_display_table_data() function retrieves and displays the data in the
Treeview widget.
def fetch_and_display_table_data(self, table_name: str):
"""Fetch and display table data."""
self.current_table = table_name
# Get columns
columns = get_table_columns(self.connection, table_name)
self.tree["columns"] = columns
self.tree["show"] = "headings"
# Add columns to treeview
for col in columns:
self.tree.heading(col, text=col)
self.tree.column(col, width=100)
# Fetch data and populate treeview
query = f"SELECT * FROM {table_name}"
data = fetch_data(self.connection, query)
# Clear existing rows
for row in self.tree.get_children():
self.tree.delete(row)
# Insert new rows
for record in data:
self.tree.insert("", tk.END, values=list(record.values()))
4. Adding a New Record
The add_record() function allows users to add a new record to the selected table. It checks
for form validation and executes an INSERT query.
def add_record(self):
"""Add a new record to the selected table."""
try:
if not self.current_table:
messagebox.showwarning("Warning", "Please select a table first!")
return
columns = get_table_columns(self.connection, self.current_table)
values = [self.entry_widgets[col].get() for col in columns]
if not all(values):
messagebox.showwarning("Validation Error", "Please fill all fields!")
return
query = f"INSERT INTO {self.current_table} ({', '.join(columns)}) VALUES ({',
'.join(['%s'] * len(columns))})"
if execute_query(self.connection, query, tuple(values)):
self.fetch_and_display_table_data(self.current_table)
messagebox.showinfo("Success", "Record added successfully!")
# Clear entry fields after successful addition
for entry in self.entry_widgets.values():
entry.delete(0, tk.END)
except Exception as e:
messagebox.showerror("Error", f"Failed to add record: {e}")
5. Creating the UI Elements
The create_entry_form() function dynamically generates a form based on the columns of
the selected table.
def create_entry_form(self):
"""Create entry form for adding records."""
if not self.current_table:
return
# Remove existing form if any
for widget in self.root.grid_slaves():
if int(widget.grid_info()["row"]) == 2:
widget.destroy()
form_frame = ttk.LabelFrame(self.root, text="Add New Record")
form_frame.grid(row=2, column=0, padx=10, pady=10, sticky="ew")
self.entry_widgets = {}
columns = get_table_columns(self.connection, self.current_table)
for idx, col in enumerate(columns):
label = ttk.Label(form_frame, text=col)
label.grid(row=idx, column=0, padx=5, pady=5)
entry = ttk.Entry(form_frame)
entry.grid(row=idx, column=1, padx=5, pady=5)
self.entry_widgets[col] = entry
submit_button = ttk.Button(form_frame, text="Add Record", command=self.add_record)
submit_button.grid(row=len(columns), column=0, columnspan=2, pady=10)
6. Running the Application
Finally, the run() method initializes and runs the Tkinter event loop.
def run(self):
"""Start the application."""
try:
self.root.mainloop()
finally:
if self.connection:
self.connection.close()
Conclusion
This project demonstrates how to use Python's Tkinter library to build a simple yet
functional database management interface.
It provides the ability to select tables, view data, and add records, all while handling
common database operations and errors.