A small desktop banking management example written in Python using tkinter for the UI and ODBC (pyodbc) to connect to a SQL Server database. The app provides CRUD operations for Department, Branch, Employee, Customer, Account, and Transaction entities and supports multi-row selection with bulk delete and basic column sorting in the tables.
- app.py — main application and UI wiring. Creates the Tk root, tabs, form handlers and calls into helpers and data modules.
- db.py — low-level DB connection factory using
pyodbc. - data.py — simple helpers:
execute(query, params=())andfetch(query)which usedb.get_connection(). - helpers.py — UI helper functions:
make_form,make_table, selection handling,tree_sort,delete_selected,_make_edit_dialog, and_format_cell. - Schema.sql — SQL schema to create the database tables (not modified by this change).
- SeedData.sql — optional seed data for the schema.
- requirements.txt — external dependency list (includes
pyodbc). - README.md — project README.
- Python 3.8+ (the repo was authored/tested on Windows).
- Install
pyodbc:
pip install -r requirements.txt- Install an appropriate ODBC driver for SQL Server (e.g., ODBC Driver 17/18 for SQL Server) or change
db.pyto match your database vendor.
- Create the database and apply the schema and seed data. Example using
sqlcmdor SSMS for SQL Server, or usingsqlite3if you adaptdb.py. - Update
db.pyconnection string if necessary (server, database, auth). - Run the app:
python app.py-
db.py— only responsibility: return a DB connection. Swap driver or connection info here to target a different server. -
data.py— thin wrapper arounddb.get_connection():execute(query, params=())— executes a parameterized statement and commits.fetch(query)— executes a read-only query and returns rows.
-
helpers.py— central UI utilities to keepapp.pysmaller:make_form(parent, fields)— builds a simple label+entry vertical form and returns a dict of Entry widgets.make_table(parent, columns, headings, with_select=False)— returns attk.Treeviewconfigured as a table. Ifwith_select=Truea selection column (_sel) is added which displays a checkbox glyph (☐/☑).- Selection handling: clicking the first column toggles the checkbox; the checkbox state is stored in the
_selcolumn value. tree_sort(tree, col, reverse=False)— sorts rows by the given column (skips the_selcolumn). Numeric values are coerced to float for numeric sorting.delete_selected(tree, delete_sql, id_pos_with_select=1, id_is_int=False, reload_callback=None)— deletes all rows that have_selset to☑. It callsdata.execute()for each selected ID and reloads the table viareload_callbackwhen provided._make_edit_dialog— small modal dialog builder for editing a single-row record._format_cell— utility to format cell values (dates, bytes, lists).
-
app.py— UI wiring and business logic per-tab. Each tab follows the same pattern:- Create a tab and form fields with
make_form. - Create a table via
make_table(..., with_select=True). - Implement
load_<entity>()which callsfetch()and inserts rows into the tree; whenwith_selectis enabled the code prepends the☐checkbox cell to each row inserted. - Implement
add_<entity>(),edit_<entity>(),delete_<entity>(), and a "Delete Selected" button that callsdelete_selectedwith a delete SQL statement.
- Create a tab and form fields with
- Tables created with
with_select=Truehave a_selcolumn as the first column. Clicking in that column toggles the checkbox glyph. - The "Delete Selected" button calls
delete_selected(tree, delete_sql, id_pos_with_select=1, id_is_int=<bool>, reload_callback=load_fn)whereid_pos_with_select=1indicates the ID column is at position 1 in thevaluestuple because_selis at position 0.
- Column headers (except the selection column) are wired to call
tree_sortwhich will reorder the rows in the tree.
- To use SQLite instead of SQL Server, update
db.pyto return ansqlite3.Connectionand adjust SQL date functions (the app usesGETDATE()in transaction inserts for SQL Server). - To use MySQL, install
mysql-connector-pythonand changedb.get_connection()accordingly.
- If the UI hangs or errors while connecting, confirm the ODBC driver is installed and the
db.pyconnection string is correct. - If
tkinterwidgets appear incorrectly, verify you are running on a supported platform and Python distribution (Windows typically bundlestkinter).
- Consider centralizing SQL for each entity (e.g.,
sql/folder or constants indata.py). - Add unit tests for
data.pyusing a test database or an in-memory SQLite alternative. - Consider using parameterized batch deletes instead of row-by-row deletes for improved performance on large selections.
If you want, I can also:
- Add inline docstrings to
helpers.pyanddata.py. - Generate an API-style reference of all functions with parameter/return details.
- Add a
requirements-dev.txtfor development tools.