基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析

发布时间:2026/6/29 18:49:02

基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析 系统整体架构与技术选型1.1 分层架构设计系统采用经典的三层架构模式实现关注点分离提升代码可维护性表示层基于PyQt5控件构建负责用户交互与数据展示。主窗口采用标签页式布局整合各业务模块通过信号/槽机制与业务层通信界面样式通过QSS统一管理实现表现与逻辑分离。业务逻辑层封装业务规则与流程控制负责参数校验、业务编排、异常处理协调数据层完成业务操作是系统的核心调度层。数据访问层通过DatabaseManager类封装所有数据库操作对外提供领域化接口内部屏蔽SQL细节与连接管理采用参数化查询保障数据安全通过事务保障写操作的原子性。横向支撑模块包括工具函数库日期处理、格式校验、数值计算与样式管理模块为各层提供通用能力。1.2 技术选型与理由技术选型选型理由Python 3.8语法简洁开发效率高标准库功能完善内置sqlite3模块无需额外依赖PyQt5控件库丰富文档完善跨平台兼容性好信号/槽机制适合模块化桌面开发SQLite嵌入式零配置数据库单文件存储便于备份迁移支持事务与标准SQL适配单机应用场景PyQtChartQt官方图表组件原生集成度高支持多种图表类型与动画效果满足数据可视化需求QSS样式表语法类似CSS可集中管理界面样式支持差异化控件定制便于主题调整1.3 核心业务流程系统核心业务围绕药品全生命周期管理展开药品信息录入 → 库存维护 → 销售登记事务性扣减库存记录流水 → 效期监控预警 → 销售数据统计分析。所有写操作均经过业务校验与事务封装确保数据完整性。二、核心模块深度实现2.1 事务性销售数据处理销售操作是系统的核心写场景涉及药品表库存更新与销售历史表记录写入两个关联操作必须保证原子性避免出现数据不一致。设计思路利用SQLite的事务支持将两个更新操作放在同一事务上下文中执行。通过上下文管理器封装数据库连接正常退出时自动提交事务发生异常时自动回滚从机制上保证数据一致性。同时在销售历史表中冗余存储药品快照信息即使后续药品记录被删除历史销售数据仍可完整追溯。核心实现def record_sale(self, sale_data):事务性提交销售订单:param sale_data: 包含drug_id, sell_quantity, sell_price, sell_amount, sell_date的字典:return: 执行成功返回Truewith self.get_connection() as conn:conn.row_factory sqlite3.Rowcursor conn.cursor()# 查询药品当前状态cursor.execute(SELECT id, stock, drug_name, spec, batch_no FROM drugs WHERE id ?,(sale_data[drug_id],))drug_info cursor.fetchone()if not drug_info:raise ValueError(目标药品不存在)if drug_info[stock] sale_data[sell_quantity]:raise ValueError(库存不足无法完成销售)# 计算库存变化remain_stock drug_info[stock] - sale_data[sell_quantity]# 更新药品主表cursor.execute(UPDATE drugsSET stock ?,sell_quantity sell_quantity ?,sell_amount sell_amount ?,sell_date ?WHERE id ?, (remain_stock, sale_data[sell_quantity],sale_data[sell_amount], sale_data[sell_date],sale_data[drug_id]))# 写入销售流水冗余存储药品快照cursor.execute(INSERT INTO sales_history (drug_id, drug_name, spec, batch_no,sell_quantity, sell_price, sell_amount,sell_date, original_stock, remaining_stock) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?), (drug_info[id], drug_info[drug_name], drug_info[spec], drug_info[batch_no],sale_data[sell_quantity], sale_data[sell_price], sale_data[sell_amount],sale_data[sell_date], drug_info[stock], remain_stock))return True调优说明采用参数化查询避免SQL注入风险单次事务内完成两次写操作减少连接开销流水表保留库存前后快照满足审计与问题排查需求2.2 基于信号/槽的模块化通信桌面应用中多模块数据同步是常见难点直接跨模块调用会导致代码耦合严重难以维护。系统利用PyQt5的信号/槽机制实现模块间的低耦合通信。设计思路为每个功能模块定义独立的更新信号当某一模块执行了影响全局数据的操作如完成销售时仅需发射对应信号其他关联模块监听信号并执行自身的数据刷新无需知道信号发射方的内部实现。实现方案class MainWindow(QMainWindow):# 定义全局数据更新信号drug_data_changed pyqtSignal()sales_data_changed pyqtSignal()def __init__(self, db_manager, username):super().__init__()self.db_manager db_managerself.username username# 信号绑定销售数据变更后刷新药品表与效期表self.sales_data_changed.connect(self.refresh_drug_table)self.sales_data_changed.connect(self.refresh_expiry_table)def submit_sales(self):# 销售提交逻辑if self.db_manager.record_sale(sale_data):# 发射数据变更信号通知关联模块刷新self.sales_data_changed.emit()QMessageBox.information(self, 成功, 销售登记完成)该方案实现了模块间的解耦新增功能模块时只需绑定对应信号无需修改原有业务代码扩展性良好。2.3 效期预警的视觉化渲染效期管理是药房系统的高频使用功能纯数字展示效率低下通过视觉化高亮可以显著提升信息获取效率。设计思路将效期预警逻辑与表格渲染分离工具函数负责计算剩余天数与对应预警等级渲染逻辑根据等级批量设置单元格样式。支持多维度筛选可快速定位不同临期等级的药品。关键实现def highlight_expiry_rows(table_widget, row_index, remaining_days):根据剩余天数为指定表格行设置预警背景色color_map {expired: QColor(#f8d7da),urgent: QColor(#fff3cd),warning: QColor(#ffe5d0),normal: None}if remaining_days 0:level expiredelif remaining_days 7:level urgentelif remaining_days 30:level warningelse:level normalbg_color color_map[level]if bg_color:for col in range(table_widget.columnCount()):item table_widget.item(row_index, col)if item:item.setBackground(bg_color)三、关键技术难点与解决方案3.1 销售操作的数据一致性问题问题表现销售操作同时涉及库存更新与流水写入若中途程序异常退出可能出现只扣库存不记流水或只记流水不扣库存的情况导致账目不符。产生原因两次数据库操作独立执行缺少原子性保障。解决方案采用数据库事务封装两次写操作利用SQLite事务的ACID特性保证操作要么全部成功要么全部回滚。通过上下文管理器自动管理事务提交与回滚避免手动处理异常遗漏。3.2 表格动态按钮的变量捕获问题问题表现在表格循环生成行内操作按钮时直接绑定槽函数会出现所有按钮都指向最后一行数据的问题。产生原因Python闭包的延迟绑定特性循环变量在槽函数触发时才会取值此时变量已变为最后一次循环的值。解决方案使用lambda表达式的默认参数进行值捕获在创建按钮时就将当前行数据绑定到函数参数中确保每个按钮对应正确的行数据。# 正确写法通过默认参数ddrug捕获当前循环值edit_btn.clicked.connect(lambda checked, ddrug: self.edit_drug(d))3.3 多页面数据同步刷新问题问题表现在销售页面完成操作后药品管理、效期管理等页面的数据不会自动更新用户需手动刷新体验不佳。产生原因各标签页独立封装缺少数据变更的通知机制。解决方案在主窗口定义全局数据变更信号各功能模块初始化时绑定对应信号。当数据发生变更时发射信号所有关联模块自动执行刷新逻辑实现一次操作、全局同步。四、系统效果与性能分析功能覆盖系统覆盖用户管理、药品进销存、销售追溯、效期预警、数据统计五大核心模块完整满足中小型药房日常运营的基础管理需求操作流程贴合实际业务场景。性能表现基于测试环境Intel i5-8250U8GB内存实测100条药品数据加载耗时约0.15秒

相关新闻