简介:这是一套面向高校学生的数据库课程设计完整项目,以Python实现酒店管理系统,适合期末大作业、课程设计及自学练手,新手也能借助详细注释快速理解。压缩包共61个文件,约8.3MB,包含18个py源码、17个pyc编译文件、8个ui界面文件、4个xml配置、3个sql脚本,以及E-R图、功能结构图、系统设计报告和课程要求PDF等文档,覆盖从数据库建表到界面交互的完整链路。项目围绕酒店管理业务展开,涉及登录、客房、员工、报表等模块,配有README与使用教程,下载后简单部署即可运行。目前已有281人学习,作者自评98分并获导师认可,可作为数据库应用课程的参考范例,帮助读者掌握Python与数据库结合开发、界面设计与文档撰写的整体思路。
1. 从一份 98 分数据库课设说起:这套 Python 酒店管理系统到底能跑出什么
如果你正在为《数据库应用》这门课的期末大作业发愁,或者想找一个能直接跑起来、代码结构清晰、还带完整设计报告的参考项目,那这套基于 Python 的酒店管理系统值得花时间拆一遍。它不是那种只有几个增删改查按钮的玩具 demo,而是把登录鉴权、客房管理、员工管理、报表统计、密码修改这些真实业务模块都做进去了,配套的 E-R 图、功能结构图、系统设计报告 PDF 一应俱全,连 Qt Designer 的 .ui 源文件都保留着,方便你改界面。技术栈上走的是 Python + PyQt5 + MySQL 这条经典课设路线,Main.py 是入口,hotelManagement.sql 是建库脚本,room.py、staff.py、report.py 分别对应客房、员工、报表三个业务模块,结构一眼能看懂。适合谁?一是赶课设 deadline 想快速搭出可演示系统的同学,二是想拿一个完整项目练手数据库设计和 PyQt 界面联动的初学者。下面我按“先跑起来、再拆结构、最后避坑”的顺序,把这份资源从头到尾过一遍。
2. 环境搭建与数据库初始化:让 Main.py 真正跑起来
2.1 依赖清单与 Python 版本选择
这套项目对 Python 版本不算挑剔,但 PyQt5 和 MySQL 驱动这两个依赖必须装对,否则 Main.py 一启动就报 ModuleNotFoundError。我一般建议用 Python 3.8 到 3.10 之间的版本,太新的 3.12 在某些 PyQt5 轮子上会有兼容性玄学。依赖装法有两种,直接 pip 或者走 requirements 文件,项目里没带 requirements.txt,所以手动装更稳。
# 建议在虚拟环境里操作,避免污染全局 python -m venv venv # Windows 激活 venv\Scripts\activate # macOS / Linux 激活 source venv/bin/activate # 安装核心依赖 pip install PyQt5 pip install PyMySQL这里解释一下为什么用 PyMySQL 而不是 mysql-connector:PyMySQL 是纯 Python 实现,不需要编译 C 扩展,在 Windows 上装起来几乎不会翻车,课设场景下够用。装完之后可以跑一句python -c "import pymysql; print(pymysql.__version__)"验证,能打印版本号就说明驱动就位。
2.2 导入 hotelManagement.sql 建库
数据库这块是整个项目的根,hotelManagement.sql 里包含了建库、建表、插入初始数据的完整语句。常见做法是用命令行导入,比图形化工具更可控,也方便你看到报错。
# 先登录 MySQL mysql -u root -p # 在 MySQL 命令行里执行 source /你的路径/hotelManagement.sql; # 或者不登录,直接一条命令导入 mysql -u root -p < /你的路径/hotelManagement.sql导入完成后用show databases;看一眼,应该能看到项目对应的库名。接着use 库名;再show tables;,正常会看到客房表、员工表、用户表这几张核心表。如果导入时报 “Unknown database”,说明 sql 文件里没有 CREATE DATABASE 语句,需要你手动先建库再导入,这是课设项目里很常见的一个小坑。
2.3 改数据库连接配置并启动
数据库建好之后,要去代码里改连接参数。项目里连接信息一般集中在某个 db 工具文件或者直接写在 Main.py 顶部,搜pymysql.connect就能定位。
# 典型连接写法,按你本机实际情况改 import pymysql conn = pymysql.connect( host='localhost', # 本机就写 localhost port=3306, # MySQL 默认端口 user='root', # 你的用户名 password='你的密码', # 改成自己的密码 database='hotel', # 改成 sql 文件里实际的库名 charset='utf8mb4' # 防止中文乱码 )参数说明:charset 一定要写 utf8mb4,不然后面插入中文客房名、员工姓名会出现乱码或者直接报错。改完保存,回到项目根目录执行python Main.py,正常情况下会弹出登录窗口。用 sql 里预置的账号登录,或者看 README.md 里写的默认账号密码。能进主界面,说明环境这条链路就通了。
3. 代码结构拆解:Main.py、room.py、staff.py 各管什么
3.1 入口与界面加载逻辑
Main.py 是整个系统的启动入口,它干的事其实不复杂:初始化 QApplication,加载 LoginUI.ui 对应的登录界面,登录成功后跳转到 MainUI.ui 主界面。PyQt5 加载 .ui 文件有两种方式,一种是运行时用 uic.loadUi 动态加载,一种是先用 pyuic5 转成 .py 再 import。这套项目两种痕迹都有,.ui 源文件和对应的 .py 文件并存,说明作者是先用 Qt Designer 画界面,再转成 Python 代码调用。
# Main.py 里典型的启动逻辑 from PyQt5 import QtWidgets from LoginUI import LoginUI # 登录界面类 if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) login_window = LoginUI() login_window.show() sys.exit(app.exec_())逻辑说明:QApplication 是每个 PyQt 程序必须有的,负责事件循环;LoginUI 是登录窗口类,实例化后 show() 显示;app.exec_() 进入主循环,窗口才会真正响应点击。如果你改了 .ui 文件但界面没变化,多半是因为程序加载的是旧的 .py 而不是 .ui,这时候要么重新用 pyuic5 转换,要么确认代码里走的是动态加载。
3.2 客房与员工模块的业务分层
room.py 和 staff.py 是业务逻辑最集中的两个文件,分别对应客房管理和员工管理。以客房模块为例,它通常包含增删改查四类操作,每类操作背后是一条 SQL 语句加一次界面刷新。
# room.py 里查询客房的典型写法 def query_rooms(self): cursor = self.conn.cursor() sql = "SELECT room_id, room_type, price, status FROM room" cursor.execute(sql) results = cursor.fetchall() # 把结果填进 QTableWidget for row_idx, row_data in enumerate(results): for col_idx, value in enumerate(row_data): self.tableWidget.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))逻辑说明:cursor 是数据库游标,execute 执行 SQL,fetchall 拿到全部结果;然后遍历结果集,逐格写入 QTableWidget。参数上要注意,如果 SQL 里带条件,比如按房型筛选,一定要用参数化查询cursor.execute(sql, (room_type,)),不要用字符串拼接,否则既有注入风险,遇到中文还容易出问题。staff.py 的结构和 room.py 几乎对称,看懂一个另一个就通了,这也是这套代码适合新手的原因——模式统一,改一处就能举一反三。
3.3 报表模块与数据统计
report.py 对应报表统计功能,一般是从多张表里聚合数据,比如统计各房型的入住率、员工数量、营收汇总。这块的 SQL 会比单表增删改查复杂一些,常见的是 JOIN 加 GROUP BY。
# report.py 里统计各房型数量的写法 def room_type_report(self): cursor = self.conn.cursor() sql = """ SELECT room_type, COUNT(*) AS total FROM room GROUP BY room_type """ cursor.execute(sql) data = cursor.fetchall() return data逻辑说明:GROUP BY 按房型分组,COUNT(*) 统计每组数量,返回的 data 是元组列表,可以喂给图表控件或者直接填表格。参数上如果要做时间范围筛选,就在 WHERE 里加日期条件,注意 MySQL 日期格式和 Python 传入的字符串格式要一致,否则查出来是空。报表模块是课设里最容易拿分也最容易翻车的部分,因为聚合逻辑一旦写错,结果对不上,答辩时一眼就被看出来。
4. 避坑与常见问题排查:那些让我返工三次的细节
4.1 中文乱码:从建库到连接的三处 charset
现象:登录后客房名、员工姓名显示成问号或者方块。原因:字符集在三个地方可能不一致——建库时、建表时、连接时。解决:建库语句用CHARACTER SET utf8mb4,连接参数加charset='utf8mb4',两头对齐基本就不会乱。如果已经建好库才发现,可以用ALTER DATABASE 库名 CHARACTER SET utf8mb4;补救。
4.2 登录报错但账号密码没错
现象:输入正确账号密码,点登录没反应或者直接崩。原因:多半是数据库连接失败被吞了异常,或者用户表里的密码字段存的是明文而代码里做了哈希比对。解决:先在代码里把连接那段的 try/except 打印出真实错误,看是连不上库还是 SQL 查不到记录;再确认 sql 里预置的密码和代码校验逻辑是否一致。
4.3 .ui 改了界面不生效
现象:用 Qt Designer 改了按钮位置,运行还是老样子。原因:程序加载的是转换后的 .py 文件,不是 .ui 源文件。解决:改完 .ui 后用pyuic5 xxx.ui -o xxx.py重新生成,或者确认代码里用的是 uic.loadUi 动态加载。这个坑我踩过不止一次,血泪经验就是改界面前先确认加载路径。
4.4 导入 sql 报外键约束错误
现象:source 导入时中途报 foreign key constraint fails。原因:sql 文件里表的创建顺序不对,子表先于父表建,或者插入数据时引用了不存在的父表记录。解决:按依赖顺序建表,先建被引用的表再建引用表;如果 sql 是别人写的顺序乱了,手动调整语句顺序,或者临时SET FOREIGN_KEY_CHECKS=0;导入完再打开。
4.5 PyQt5 装完仍报 no module named PyQt5
现象:pip 显示安装成功,运行还是找不到模块。原因:装到了全局 Python 而运行用的是虚拟环境,或者反过来。解决:确认which python和pip -V指向同一个环境,在虚拟环境里重装一次。这个属于环境玄学,但排查起来就是一句话的事。
5. 二次开发与答辩加分技巧:把课设改成你自己的项目
跑通只是第一步,真正让导师认可的是你能说清楚为什么这么设计,以及在此基础上做了什么改进。这套项目留了不少可扩展的口子,我一般会从三个方向动手。第一是给报表模块加图表,PyQt5 里可以嵌 matplotlib 或者用 QtChart,把 report.py 查出来的聚合数据画成柱状图,答辩时视觉冲击力直接拉满。第二是给客房状态加实时刷新,用 QTimer 定时查库更新界面,模拟真实酒店系统的房态变化。第三是补一层简单的权限控制,在用户表里加 role 字段,登录后根据角色决定哪些菜单可见,这个改动不大但能体现你对业务的理解。
# 用 QTimer 定时刷新房态的思路 from PyQt5.QtCore import QTimer self.timer = QTimer() self.timer.timeout.connect(self.query_rooms) # 复用查询函数 self.timer.start(5000) # 每 5 秒刷新一次逻辑说明:QTimer 每隔设定毫秒触发一次 timeout 信号,连接到查询函数就实现了自动刷新。参数 5000 是毫秒,按需调整,太短会增加数据库压力,太长又失去实时感。验证方法很简单,开两个客户端,一个改房态,另一个看是否在几秒内同步。
另外,答辩前一定要把 E-R 图和 Functional_structure_diagram.png 吃透,导师最爱问的就是“你这个实体之间的关系是怎么设计的”“为什么客房和订单是一对多”。项目里这两张图已经画好了,你要做的是能用自己的话讲出来。从那以后我每次拿到别人的课设项目,都强制先跑通再拆结构最后想扩展点,这套流程走下来,答辩基本不会慌。希望这份拆解能帮你少走点弯路,把这份资源真正用起来。
本文还有配套的精品资源,点击获取