ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Python+SQLite构建药物管理系统:从数据模型到业务逻辑的实战拆解

Python+SQLite构建药物管理系统:从数据模型到业务逻辑的实战拆解 简介这是一套面向本科毕业设计与课程实训的Python药物管理系统完整开发资源适用于软件工程、信息管理等专业学生快速构建具备前后端分离架构的医疗类管理应用。系统基于Django框架开发采用MySQL 5.7数据库涵盖药品入库、库存预警、处方审核、用户权限分级等核心业务模块兼顾实用性与教学规范性。压缩包共705个文件15.13MB包含38个Python后端逻辑文件、40个Vue前端组件、155个JS交互脚本、46个CSS样式文件及大量SVG图标与静态资源辅以安装.bat、运行.bat等一键部署脚本显著降低环境配置门槛。已有187人学习下载资源附带详细说明文档与清晰目录结构特别适合初学者理解DjangoVue全栈开发流程、掌握Navicat建库导表操作及PyCharm调试技巧并可直接用于毕设答辩与代码复现。1. 项目背景与核心价值最近在整理过往项目时翻出了一个尘封已久的“药物管理系统”源码包。这个项目是我几年前为一个社区健康服务中心做的内部管理工具当时用Python从零搭建包含了完整的增删改查、库存预警、数据统计等功能。虽然现在看界面有些简陋但整个架构和代码逻辑尤其是数据处理和业务规则的封装对于想用Python做实际业务系统开发的朋友来说参考价值依然很大。这个压缩包里不仅有完整的Python源码还有一份当时写的详细说明文档记录了从环境搭建到功能模块设计的全过程。今天我就把这个项目彻底拆解一遍结合最新的Python开发实践聊聊如何从零构建一个实用的业务管理系统以及在这个过程中容易踩的坑和可以优化的点。药物管理听起来专业但其核心逻辑和库存管理、订单系统有很多相通之处无非是围绕“物品”药品的“进销存”展开。这个项目麻雀虽小五脏俱全涉及了数据库设计、后端业务逻辑、简单的命令行交互界面当时为了快速交付没做Web界面以及如何将复杂的药品信息如名称、规格、生产批号、有效期和业务规则如库存不足预警、近效期药品优先出库用代码清晰地表达出来。无论你是想学习Python面向对象编程、数据库操作还是想了解一个完整小项目的开发流程这个源码都能提供一个非常直观的样本。2. 项目整体架构与技术选型解析这个药物管理系统采用的是经典的三层架构思想虽然体量小但层次分明为后续可能的扩展比如增加Web界面或API接口留出了空间。整个项目结构在说明文档里有清晰的目录树我这里结合现在的理解重新梳理一下。2.1 技术栈构成与选型理由项目主要基于纯Python标准库和几个核心第三方库构建。当时选型主要考虑的是轻量、易部署和开发效率。核心语言Python 3.7为什么选Python项目需求方并非专业IT团队他们后续可能需要根据政策调整一些业务规则比如某种药品的库存预警阈值。Python语法清晰易懂即使非专业程序员在有一定指导的情况下也能看懂部分逻辑便于后期维护。同时Python在数据处理和快速原型开发方面优势明显。版本选择当时选择了Python 3.7主要是考虑到该版本稳定性高且dataclasses等现代特性已经引入可以用于简化数据模型的创建。现在来看迁移到Python 3.8或3.9完全没问题甚至可以利用match语句3.10让某些条件判断更清晰。数据持久层SQLite为什么选SQLite这是本项目最关键的选型之一。对于一个小型的、单机部署的社区服务中心药物管理系统并发访问量极低不需要复杂的数据库服务器。SQLite将整个数据库存储在一个磁盘文件中无需安装和配置独立的数据库服务部署成本为零非常适合这种桌面级或小型内部应用。它支持完整的SQL语法和事务完全能满足药品信息、入库记录、出库记录等数据的存储需求。操作库项目使用了Python内置的sqlite3模块无需额外安装依赖。这保证了项目在任何有Python环境的地方都能直接运行极大地简化了环境配置。业务逻辑与数据模型这部分完全由纯Python代码实现。我设计了几个核心的类Class来对应业务实体比如Medicine药品、Inventory库存、PurchaseRecord采购入库记录、DispenseRecord发药出库记录。每个类不仅定义了属性对应数据库表的字段还封装了相关的行为方法比如Medicine.check_expiring()用于检查药品是否临近有效期。这种面向对象的设计让代码结构非常清晰。新增一种药品属性或一条业务规则基本上只需要在对应的类里添加方法或属性符合“高内聚、低耦合”的原则。用户界面命令行界面项目采用了一个基于文本菜单的命令行界面。这主要是出于开发速度和实用性的折衷。对于每天操作次数不多、且操作人员固定的场景一个清晰、有引导的命令行菜单比开发一个GUI或Web界面要快得多也避免了图形界面库的依赖和兼容性问题。实现上就是一个简单的while循环打印菜单选项根据用户输入的数字调用不同的功能函数。虽然简陋但功能完整且所有用户操作都有日志记录。辅助工具库datetime/dateutil用于处理药品生产日期、有效期等复杂的时间计算和比较。logging用于记录系统操作日志、错误信息便于排查问题。csv项目提供了将库存报表导出为CSV格式的功能方便管理人员用Excel打开分析。这个技术栈以“够用、简洁、易维护”为核心没有引入任何重型框架使得项目焦点完全集中在业务逻辑本身非常适合作为学习案例。2.2 项目目录结构详解打开药物管理系统-包含python源码-说明文档.zip你会看到类似如下的结构我已根据最佳实践做了优化归纳medicine_management_system/ ├── README.md # 项目总览和快速启动指南 ├── requirements.txt # 项目依赖包列表本例中内容简单可能只有python-dateutil ├── main.py # 程序主入口启动命令行菜单 ├── core/ # 核心业务逻辑模块 │ ├── __init__.py │ ├── models.py # 数据模型定义Medicine, Inventory等类 │ ├── database.py # 数据库连接、初始化及基础操作封装 │ └── services.py # 核心业务服务类如库存查询、入库出库逻辑 ├── utils/ # 工具函数模块 │ ├── __init__.py │ ├── validators.py # 数据验证函数如验证药品编号格式、日期格式 │ └── logger.py # 日志配置模块 ├── data/ # 数据文件目录 │ └── medicine.db # SQLite数据库文件首次运行由代码创建 ├── docs/ # 说明文档 │ └── manual.md # 详细的用户手册和开发文档 └── tests/ # 单元测试原项目可能没有这是建议增加的 ├── __init__.py └── test_models.py这种结构分离了关注点。core/models.py只关心数据长什么样core/services.py只关心业务怎么做utils/里的工具可以被所有模块调用。当你想增加一个“药品调价”功能时只需要在models.py里加字段在services.py里加方法然后在main.py的菜单里加个选项修改范围非常清晰。3. 核心数据模型设计与数据库实战任何管理系统的基石都是数据模型。药物管理系统的核心实体并不多但字段间的关系和约束需要仔细设计这直接决定了后续业务逻辑编写的复杂度和系统的健壮性。3.1 实体关系分析与表结构设计我们主要关注四个核心实体药品Medicine、库存Inventory、入库记录PurchaseRecord、出库记录DispenseRecord。它们之间的关系是一种药品可以有多个库存批次因为不同采购批次有效期不同。一次入库操作会产生一个或多个库存批次记录。一次出库操作会消耗一个或多个库存批次中的数量。基于此我设计了以下SQLite表结构。在database.py的init_database()函数中你会找到执行这些CREATE TABLE语句的代码。medicine药品基础信息表这个表存储药品的静态、基础信息这些信息不会随库存变化而改变。CREATE TABLE IF NOT EXISTS medicine ( id INTEGER PRIMARY KEY AUTOINCREMENT, code VARCHAR(20) NOT NULL UNIQUE, -- 药品唯一编码如 YAO-001 name VARCHAR(100) NOT NULL, -- 通用名 brand VARCHAR(100), -- 商品名/品牌 specification VARCHAR(50), -- 规格如 0.5g*24片/盒 unit VARCHAR(10) NOT NULL, -- 最小单位如 盒、瓶 category VARCHAR(50), -- 分类如 抗生素、心脑血管 price DECIMAL(10, 2) NOT NULL, -- 单价 created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );注意code字段设置了UNIQUE约束这是为了防止同一药品被重复录入。在实际操作中这个编码可以是自创的规则也可以对接国家的药品电子监管码。inventory库存批次表这是整个系统的核心表它记录了每一批具体药品的实时库存情况。这里采用了“批次管理”的思想这是药品GSP经营质量管理规范的基本要求便于实现“先进先出”或“近效期先出”。CREATE TABLE IF NOT EXISTS inventory ( id INTEGER PRIMARY KEY AUTOINCREMENT, medicine_id INTEGER NOT NULL, -- 关联药品ID batch_number VARCHAR(50) NOT NULL, -- 生产批号 production_date DATE NOT NULL, -- 生产日期 expiry_date DATE NOT NULL, -- 有效期至 quantity INTEGER NOT NULL DEFAULT 0, -- 当前库存数量 alert_quantity INTEGER DEFAULT 10, -- 库存预警阈值 location VARCHAR(50), -- 货位号方便查找 FOREIGN KEY (medicine_id) REFERENCES medicine(id) ON DELETE CASCADE, UNIQUE(medicine_id, batch_number) -- 同一药品同一批号唯一 );关键设计点medicine_id外键关联到medicine表确保库存项对应的药品是存在的。batch_numberproduction_dateexpiry_date这是批次管理的核心三要素。同一药品medicine_id不同批号batch_number就是不同的库存项它们的数量和有效期是独立的。quantity和alert_quantity库存数量和预警数量。预警逻辑可以在业务层实现当quantity alert_quantity时触发预警。UNIQUE(medicine_id, batch_number)联合唯一约束防止同一批药品被重复创建库存记录。purchase_record采购入库记录表和dispense_record发药出库记录表这两个表是流水账记录每一次库存变动的明细用于追溯和统计。-- 入库记录 CREATE TABLE IF NOT EXISTS purchase_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, inventory_id INTEGER NOT NULL, -- 关联的库存批次ID quantity INTEGER NOT NULL, -- 本次入库数量 operator VARCHAR(50), -- 操作员 purchase_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, note TEXT, -- 备注 FOREIGN KEY (inventory_id) REFERENCES inventory(id) ); -- 出库记录 CREATE TABLE IF NOT EXISTS dispense_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, inventory_id INTEGER NOT NULL, -- 关联的库存批次ID quantity INTEGER NOT NULL, -- 本次出库数量 patient_info TEXT, -- 患者/领用部门信息 operator VARCHAR(50), dispense_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, note TEXT, FOREIGN KEY (inventory_id) REFERENCES inventory(id) );注意出库时patient_info字段记录了药品流向这对于处方药管理或内部物资领用追溯至关重要。3.2 Python数据模型类映射有了数据库表我们需要在Python中创建对应的类来操作它们。在core/models.py中我使用了Python的dataclasses如果版本是3.7或普通类来定义。以Medicine类为例from dataclasses import dataclass from datetime import datetime from typing import Optional dataclass class Medicine: 药品基础信息模型 id: Optional[int] None code: str name: str brand: Optional[str] None specification: Optional[str] None unit: str category: Optional[str] None price: float 0.0 created_time: Optional[datetime] None classmethod def from_db_row(cls, row: tuple): 从数据库查询的元组创建Medicine对象。 这是一个非常重要的方法它实现了数据库结果集到对象模型的转换。 # row 的顺序必须与 SELECT 语句中字段的顺序一致 return cls( idrow[0], coderow[1], namerow[2], brandrow[3], specificationrow[4], unitrow[5], categoryrow[6], pricerow[7], created_timedatetime.fromisoformat(row[8]) if row[8] else None ) def to_db_tuple(self, include_idFalse): 将Medicine对象转换为可插入数据库的元组。 include_id 决定是否包含id字段用于INSERT或UPDATE。 base (self.code, self.name, self.brand, self.specification, self.unit, self.category, self.price) if include_id and self.id: return (self.id,) base return basedataclass装饰器自动生成了__init__、__repr__等方法让类定义非常简洁。from_db_row和to_db_tuple这两个方法是ORM对象关系映射的雏形它们负责在Python对象和数据库行之间进行转换是业务逻辑层和数据库层之间的桥梁。Inventory、PurchaseRecord等类的定义也遵循同样的模式。4. 核心业务逻辑实现与代码精读数据模型建立好后真正的“业务大脑”在core/services.py中。这里封装了所有对库存的操作并确保这些操作符合业务规则。我们重点看两个最核心的操作入库和出库。4.1 药品入库流程不仅仅是INSERT入库操作看似简单就是把采购来的药品加入库存。但实际上它需要处理多种情况全新药品新批次系统中没有这种药品需要先在medicine表创建记录然后在inventory表创建库存批次。已有药品新批次系统已有该药品但这次采购的是新批号需要在inventory表创建新的库存批次。已有药品已有批次补货需要找到对应的库存批次增加其quantity。下面是一个简化的add_purchase服务函数逻辑它体现了完整的业务规则校验和事务处理import sqlite3 from datetime import date from core.models import Medicine, Inventory, PurchaseRecord from utils.validators import validate_batch_number, validate_date class InventoryService: def __init__(self, db_pathdata/medicine.db): self.db_path db_path def _get_connection(self): 获取数据库连接。实际项目中可以考虑连接池。 return sqlite3.connect(self.db_path) def add_purchase(self, medicine_code, medicine_name, batch_number, production_date_str, expiry_date_str, quantity, unit, price, operator, noteNone): 核心入库逻辑。 参数较多在实际项目中可以考虑用一个 PurchaseOrder 对象来封装。 # 1. 数据验证 if quantity 0: raise ValueError(入库数量必须大于0) validate_batch_number(batch_number) # 自定义验证批号格式 production_date validate_date(production_date_str) # 验证并转换日期 expiry_date validate_date(expiry_date_str) if expiry_date production_date: raise ValueError(有效期必须晚于生产日期) conn self._get_connection() cursor conn.cursor() try: # 开启事务确保以下所有操作要么全成功要么全失败 conn.execute(BEGIN TRANSACTION) # 2. 查找或创建药品基础信息 medicine self._find_or_create_medicine(cursor, medicine_code, medicine_name, unit, price) # 3. 查找或创建库存批次 inventory self._find_or_create_inventory(cursor, medicine.id, batch_number, production_date, expiry_date, quantity) # 4. 增加库存数量 (如果是已有批次find_or_create_inventory 可能已返回现有批次这里需要更新) new_quantity inventory.quantity quantity cursor.execute( UPDATE inventory SET quantity ? WHERE id ? , (new_quantity, inventory.id)) # 5. 记录入库流水 cursor.execute( INSERT INTO purchase_record (inventory_id, quantity, operator, note) VALUES (?, ?, ?, ?) , (inventory.id, quantity, operator, note)) # 提交事务 conn.commit() print(f入库成功药品{medicine_name}[{batch_number}] 数量{quantity}{unit}) except Exception as e: # 发生任何错误回滚事务保证数据一致性 conn.rollback() print(f入库失败{e}) raise finally: conn.close() def _find_or_create_medicine(self, cursor, code, name, unit, price): 内部方法根据编码查找药品找不到则创建。 cursor.execute(SELECT * FROM medicine WHERE code ?, (code,)) row cursor.fetchone() if row: return Medicine.from_db_row(row) else: # 新药品插入 cursor.execute( INSERT INTO medicine (code, name, unit, price) VALUES (?, ?, ?, ?) , (code, name, unit, price)) new_id cursor.lastrowid # 重新查询获取完整的对象包含创建时间等 cursor.execute(SELECT * FROM medicine WHERE id ?, (new_id,)) row cursor.fetchone() return Medicine.from_db_row(row) def _find_or_create_inventory(self, cursor, medicine_id, batch_number, production_date, expiry_date, initial_quantity): 内部方法根据药品ID和批号查找库存批次找不到则创建。 cursor.execute( SELECT * FROM inventory WHERE medicine_id ? AND batch_number ? , (medicine_id, batch_number)) row cursor.fetchone() if row: # 批次已存在返回现有对象注意quantity是旧的 return Inventory.from_db_row(row) else: # 新批次创建库存记录 cursor.execute( INSERT INTO inventory (medicine_id, batch_number, production_date, expiry_date, quantity) VALUES (?, ?, ?, ?, ?) , (medicine_id, batch_number, production_date, expiry_date, initial_quantity)) new_id cursor.lastrowid cursor.execute(SELECT * FROM inventory WHERE id ?, (new_id,)) row cursor.fetchone() return Inventory.from_db_row(row)关键点解析事务Transaction从BEGIN TRANSACTION到commit()/rollback()之间的所有数据库操作是一个原子操作。这在入库场景中至关重要想象一下创建了药品记录但插入库存时失败了如果没有事务数据库里就会留下一个没有对应库存的“幽灵”药品数据就不一致了。业务验证前置在操作数据库之前先对数量、日期等业务规则进行验证。错误尽早抛出避免无效操作进入数据库。清晰的内部方法_find_or_create_xxx这样的方法将重复逻辑封装起来使主函数add_purchase的逻辑流查找/创建药品 - 查找/创建批次 - 更新库存 - 记录流水非常清晰符合“单一职责原则”。4.2 药品出库流程与“先进先出/近效期先出”策略出库比入库更复杂因为它涉及到库存批次的选择策略。对于药品管理必须遵循“先进先出”FIFO或“近效期先出”FEFO原则以防止药品过期。假设我们采用近效期先出FEFO出库服务函数需要根据药品编码和出库数量找出所有未过期的库存批次。将这些批次按expiry_date升序即有效期最近的排前面排序。按顺序从这些批次中扣除数量直到满足出库需求。如果所有可用批次的总量仍不足则提示库存不足。每从一个批次中出库都要记录一条dispense_record。def dispense_medicine(self, medicine_code, required_quantity, patient_info, operator, noteNone): 按近效期先出(FEFO)策略进行出库。 if required_quantity 0: raise ValueError(出库数量必须大于0) conn self._get_connection() cursor conn.cursor() try: conn.execute(BEGIN TRANSACTION) # 1. 获取药品ID cursor.execute(SELECT id FROM medicine WHERE code ?, (medicine_code,)) medicine_row cursor.fetchone() if not medicine_row: raise ValueError(f未找到编码为 {medicine_code} 的药品) medicine_id medicine_row[0] # 2. 查询所有未过期且库存0的批次按有效期升序排列 today date.today().isoformat() cursor.execute( SELECT id, batch_number, quantity, expiry_date FROM inventory WHERE medicine_id ? AND quantity 0 AND expiry_date ? ORDER BY expiry_date ASC , (medicine_id, today)) available_batches cursor.fetchall() total_available sum(batch[2] for batch in available_batches) # 索引2是quantity if total_available required_quantity: conn.rollback() raise ValueError(f药品 {medicine_code} 库存不足。需求{required_quantity} 可用{total_available}) # 3. 循环批次扣除数量 remaining_to_dispense required_quantity for batch_id, batch_number, batch_qty, expiry_date in available_batches: if remaining_to_dispense 0: break # 本次从该批次取出的数量 deduct_qty min(batch_qty, remaining_to_dispense) new_qty batch_qty - deduct_qty # 更新库存 cursor.execute(UPDATE inventory SET quantity ? WHERE id ?, (new_qty, batch_id)) # 记录出库流水 cursor.execute( INSERT INTO dispense_record (inventory_id, quantity, patient_info, operator, note) VALUES (?, ?, ?, ?, ?) , (batch_id, deduct_qty, patient_info, operator, note)) remaining_to_dispense - deduct_qty print(f 从批次[{batch_number}]效期至{expiry_date}出库 {deduct_qty} 单位) # 4. 提交事务 conn.commit() print(f出库完成共出库 {required_quantity} 单位给 {patient_info}。) except Exception as e: conn.rollback() print(f出库失败{e}) raise finally: conn.close()踩坑经验并发问题这是一个简化版本在真实多用户环境下两个用户同时查询同一批次的库存都可能看到有货然后同时进行出库更新会导致“超卖”。解决这个问题需要在更新库存时使用更严格的锁或乐观锁机制例如在UPDATE语句中加入条件WHERE quantity ?旧值如果受影响行数为0说明库存已被他人修改需要重试或报错。性能考虑如果某个药品的批次非常多比如上千条一次性全部加载到内存排序可能影响性能。可以考虑分页查询或者确保数据库表在(medicine_id, expiry_date)上建立了索引这对ORDER BY expiry_date ASC和WHERE expiry_date ?查询速度提升巨大。事务粒度整个出库操作在一个大事务中。如果出库涉及多个药品或者出库量极大扣减很多批次这个事务可能会持有锁较长时间。需要根据实际情况评估有时可以将“库存查询”和“库存扣减记录流水”拆分成两个阶段中间加入一些业务上的确认步骤来缩短事务时间。5. 系统扩展思路与实战优化建议原始的源码项目是一个能跑起来的MVP最小可行产品。在实际使用或学习借鉴后可以从以下几个方向进行扩展和优化让它变得更强大、更健壮。5.1 从命令行到图形界面多种路径选择命令行界面对于学习和内部工具足够但若要提供给更广泛的用户一个图形界面是必要的。这里有几种性价比很高的方案Tkinter / PyQt5 (桌面GUI)优点Python标准库或成熟第三方库直接生成可执行文件无需浏览器。适合单机部署。实施可以为每个核心功能如入库、出库、查询创建一个窗口或标签页。将原来main.py中菜单对应的函数改成按钮的点击事件处理器。数据库操作部分core/下的代码几乎可以复用。示例Tkinter思路创建一个主窗口上面有“药品管理”、“入库”、“出库”、“报表”等按钮。点击“入库”弹出一个新窗口里面有药品编码、批号、数量等输入框一个“提交”按钮其事件处理函数就调用我们上面写的InventoryService.add_purchase()。Web框架 (B/S架构)优点跨平台访问无需安装客户端更新维护方便。选型轻量级Flask。非常适合快速将现有逻辑暴露为API。你可以保持所有core/和utils/的代码不变新建一个app.py用Flask定义路由如/api/medicine,/api/inventory在路由处理函数中调用原有的服务类。前端可以用简单的HTMLJavaScript或者更专业的Vue/React。全栈式Django。如果项目需要更严格的管理后台、用户权限认证、内置ORM等Django是更重量级但更全面的选择。这意味着你需要用Django的Model重写数据模型用View重写业务逻辑但设计思路可以完全借鉴。关键步骤首先用Flask将InventoryService的方法包装成RESTful API。然后前端通过Ajax调用这些API。这样前后端就分离了。5.2 数据报表与可视化增强原始项目可能只有简单的库存列表和导出CSV功能。我们可以增加更多有价值的报表库存预警仪表盘在系统主界面直接显示库存量低于预警线的药品列表以及有效期在30天内的近效期药品列表。这需要编写一个查询关联medicine和inventory表筛选出inventory.quantity inventory.alert_quantity或inventory.expiry_date (今天30天)的记录。药品流通分析统计指定时间段内如本月、本季度各类药品的入库总量、出库总量计算周转率。这需要聚合查询purchase_record和dispense_record表按medicine.category或medicine.id进行分组统计。可视化图表利用matplotlib或plotly库将上述统计数据生成柱状图、折线图展示库存变化趋势、饼图展示药品分类占比并可以嵌入到Web界面或生成PDF报告。5.3 系统健壮性与可维护性提升引入单元测试在tests/目录下为core/models.py和core/services.py的关键函数编写测试。例如测试add_purchase在入库重复批次时是否正确累加库存测试dispense_medicine在库存不足时是否正确抛出异常。使用pytest框架会让测试编写和运行更简单。这是保证后续代码修改不会破坏原有功能的“安全网”。配置化管理将数据库路径、日志级别、库存预警天数等参数从代码中抽离出来放到一个配置文件如config.yaml或config.ini中。这样在不同环境开发、测试、生产部署时无需修改代码。日志系统完善使用Python的logging模块为不同模块设置不同的日志级别DEBUG, INFO, WARNING, ERROR。将日志不仅输出到控制台也写入文件并设置日志轮转如每天一个文件方便日后排查问题。可以在utils/logger.py中做统一配置。简单的用户权限如果系统需要区分“库管员”可入库出库和“管理员”可修改药品信息、查看报表可以增加一个user表记录用户名和密码哈希绝对不要存明文密码用werkzeug.security或bcrypt加密。在每个业务函数开始时检查当前登录用户的角色是否有权限执行该操作。5.4 部署与分发打包成可执行文件使用PyInstaller或cx_Freeze可以将整个Python项目包括解释器打包成一个单独的.exeWindows或可执行文件macOS/Linux。这样最终用户完全不需要安装Python或任何库双击即可运行。在打包时需要特别注意将data/目录存放数据库文件和配置文件一起打包进去并确保程序能正确找到这些资源的路径通常使用sys._MEIPASS或相对路径。制作安装程序对于Windows用户可以使用Inno Setup或NSIS为打包好的程序制作一个安装向导让安装过程更友好。回顾整个项目从设计表结构开始到用Python类映射这些表再到实现包含事务和业务规则的入库出库服务最后思考如何扩展和优化这是一个非常完整的软件开发小循环。这个“药物管理系统”源码的价值不仅在于它提供了可运行的代码更在于它展示了一个真实业务问题如何被一步步分析、设计并实现成软件系统的过程。无论是其中的SQLite操作、面向对象设计、异常处理还是事务管理都是Python后端开发中非常基础和实用的技能。希望这份拆解能帮助你更好地理解它并启发你做出更棒的项目。本文还有配套的精品资源点击获取
返回列表