尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python+SQLite实现家庭药箱药品信息管理命令行工具

Python+SQLite实现家庭药箱药品信息管理命令行工具 最近整理家里的药箱发现三盒藿香正气类产品摆在一起一瓶藿香正气水、一盒藿香正气软胶囊、一袋藿香正气颗粒。外包装上都写着“解表化湿、理气和中”但剂型不同、用法不同保质期和生产批号也不一样。很多人习惯把藿香正气类口服制剂昵称为“藿藿”可这个昵称背后对应的是完全不同的药品形态和存储要求。如果没有统一记录很容易出现过期、重复购买、用量混淆的情况。与其继续靠记忆和纸质小票管理药品不如直接用 Python 和 SQLite 做一个家庭药品信息管理命令行工具。把散落的药品信息集中管理顺带把有效期提醒、库存统计、用药记录都做了。这篇文章会把完整思路、表结构设计、可复制代码、运行演示和常见坑点全部拆开讲清楚。适合想练手 Python 项目的新手也适合需要一套本地化数据管理方案的开发者参考。1. 为什么用“藿藿”作为案例来管理药品数据1.1 “藿藿”到底是什么“藿藿”并不是一个标准的药品通用名而是网友对藿香正气类口服制剂的通俗叫法。严格来说藿香正气类产品包括藿香正气水、藿香正气口服液、藿香正气软胶囊、藿香正气滴丸、藿香正气颗粒等多种剂型。它们的主要成分相似都含有广藿香油、紫苏叶油、苍术、陈皮、厚朴、白芷、茯苓、大腹皮、半夏、甘草等药材。但不同剂型的辅料、溶剂、酒精含量、用法用量差别很大。比如传统藿香正气水含有乙醇对酒精敏感的人群需要特别注意藿香正气口服液则通常不含酒精口感相对柔和。软胶囊和滴丸的携带更方便但起效方式和服用方法不同。这就引出一个现实问题药品名称相似不代表可以互相替代。家庭药箱里很可能同时存在几种剂型怎么记录才不会混淆答案是建一张结构化的药品信息表。1.2 家庭药品管理的三个痛点结合实际经验家庭药箱管理通常面对三个问题第一个是有效期管理。药品包装上的有效期格式并不统一有的写“2026.09”有的写“2026/09/30”还有的写“有效期至2026年9月”。人工肉眼核对容易漏掉临期药品。第二个是重复购买。家属去药店买药时常常记不清家里还剩多少看到“藿香正气”就顺手再买一盒结果造成库存积压过期只能扔掉。第三个是信息分散。药品说明书、购买小票、生产批号、用法用量分散在纸盒和手机照片里真正需要时翻半天找不到。用数据库来管理本质上就是把“药品名、剂型、规格、批号、有效期、库存、存储条件、备注”这些字段统一收拢。后续查库存、查有效期、查买过什么都只需要一条 SQL 语句。1.3 为什么选择 Python SQLite 的组合SQLite 是一个轻量级嵌入式数据库不需要单独安装数据库服务数据保存在一个.db文件中拷贝即备份非常适合家庭级、个人级的应用场景。Python 标准库自带了sqlite3模块不需要额外安装第三方数据库驱动。相比直接写 Excel 表格用 SQLite 的好处是数据约束更强可以设置主键、外键、非空字段。查询能力强支持WHERE、LIKE、ORDER BY、日期函数。数据规模小但依然具备完整的关系型数据库能力。后续想迁移到 MySQL、PostgreSQL逻辑基本可以复用。所以这篇文章的实战案例就是用 Python 操作 SQLite从零搭建一套药品信息管理工具以“藿藿”类产品作为演示数据。安全声明本文是信息技术与数据管理笔记不构成任何医疗建议。药品使用请以说明书和医生指导为准。2. 环境准备与项目结构2.1 环境版本说明本文示例在以下环境验证通过代码整体兼容性较好不强制要求具体小版本操作系统Windows 10 / macOS 13 / Ubuntu 22.04 均可Python3.10 及以上版本数据库SQLitePython 自带第三方库pandas、openpyxl用于导出 Excel可选安装版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。先创建一个虚拟环境避免污染系统全局 Python 环境mkdir medicine-manager cd medicine-manager python -m venv venvWindows 下激活虚拟环境venv\Scripts\activatemacOS / Linux 下激活虚拟环境source venv/bin/activate如果后续要导出 Excel 报表安装 pandas 和 openpyxlpip install pandas openpyxl2.2 项目目录结构建议按下面的结构组织文件把数据库连接、业务逻辑、命令行入口分开便于维护和测试medicine-manager/ ├── venv/ ├── data/ │ └── medicine.db ├── db.py ├── models.py ├── cli.py ├── export_excel.py ├── requirements.txt └── README.md其中data/medicine.db是 SQLite 数据库文件运行程序后自动生成。db.py负责数据库连接和建表。models.py封装药品和用药记录的增删改查函数。cli.py是命令行交互入口。export_excel.py负责把数据库内容导出为 Excel 报表。requirements.txt记录第三方依赖。创建依赖文件pandas2.0.0 openpyxl3.1.02.3 初始化数据库第一次运行前先执行建表脚本。数据库连接逻辑写在db.py中# 文件路径db.py import sqlite3 from pathlib import Path BASE_DIR Path(__file__).parent DATA_DIR BASE_DIR / data DATA_DIR.mkdir(exist_okTrue) DB_PATH DATA_DIR / medicine.db def get_connection(): 获取数据库连接开启外键约束。 conn sqlite3.connect(DB_PATH) conn.row_factory sqlite3.Row conn.execute(PRAGMA foreign_keys ON) return conn def init_db(): 初始化数据库表结构。 sql CREATE TABLE IF NOT EXISTS medicines ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, generic_name TEXT, category TEXT, dosage_form TEXT, spec TEXT, manufacturer TEXT, batch_no TEXT, expire_date TEXT NOT NULL, stock_count INTEGER NOT NULL DEFAULT 0, storage TEXT, remark TEXT, created_at TEXT NOT NULL DEFAULT (datetime(now, localtime)), updated_at TEXT NOT NULL DEFAULT (datetime(now, localtime)) ); CREATE TABLE IF NOT EXISTS usage_records ( id INTEGER PRIMARY KEY AUTOINCREMENT, medicine_id INTEGER NOT NULL, user_name TEXT, dosage TEXT, taken_at TEXT NOT NULL, note TEXT, FOREIGN KEY (medicine_id) REFERENCES medicines(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_medicines_expire_date ON medicines(expire_date); CREATE INDEX IF NOT EXISTS idx_medicines_name ON medicines(name); with get_connection() as conn: conn.executescript(sql)这里需要注意的是PRAGMA foreign_keys ON必须在每次连接时手动开启SQLite 默认不启用外键约束。row_factory sqlite3.Row让查询结果可以通过字段名访问比下标更直观。3. 数据模型与核心逻辑设计3.1 药品主表字段说明药品主表medicines的字段设计如下字段名类型说明idINTEGER主键自增nameTEXT商品名例如“藿香正气水”generic_nameTEXT通用名例如“藿香正气水”categoryTEXT分类例如“中成药/解表剂”dosage_formTEXT剂型例如“酊剂”“口服液”“软胶囊”specTEXT规格例如“10ml*10支”manufacturerTEXT生产企业batch_noTEXT生产批号expire_dateTEXT有效期推荐统一为 YYYY-MM-DDstock_countINTEGER库存数量默认 0storageTEXT存储条件例如“密封置阴凉干燥处”remarkTEXT备注created_atTEXT创建时间updated_atTEXT更新时间这里有几个设计考虑。expire_date统一存成YYYY-MM-DD格式这样可以直接用字符串比较判断是否过期也能用 SQLite 的date()函数计算剩余天数。stock_count必须是整数避免出现“半盒”这种无法量化的库存。如果药品是按板、按袋保存可以约定最小库存单位比如“1盒 10支”备注里写清楚。batch_no特别重要。同一款药不同批号的有效期可能不同。单独记录批号可以更精确地做临期预警。3.2 用药记录表设计usage_records表记录每一次实际用药情况字段名类型说明idINTEGER主键自增medicine_idINTEGER外键关联 medicines.iduser_nameTEXT用药人dosageTEXT用量例如“一次10ml”taken_atTEXT用药时间ISO 格式noteTEXT备注为什么需要这张表因为日常用药往往会忘。有了记录表就可以回答“上次吃是什么时候”“一共用过几盒”“家庭成员分别用过什么药”这些问题。更重要的是删除药品时通过外键级联删除关联记录避免孤儿数据。3.3 日期处理方式Python 的datetime模块负责日期解析和格式化。为了避免混乱程序统一约定输入日期推荐使用YYYY-MM-DD。如果用户输入2026.09程序自动补全为2026-09-30这种形式并按当月最后一天处理。存储到数据库的日期始终是YYYY-MM-DD。有效性判断逻辑是剩余天数大于 0 且小于等于 30 天视为“临期”剩余天数小于 0视为“已过期”。4. 完整代码实现4.1 药品增删改查模块models.py封装业务操作所有函数都接收conn连接对象方便后续测试和事务控制。# 文件路径models.py import sqlite3 from datetime import datetime, date def add_medicine(conn, name, generic_name, category, dosage_form, spec, manufacturer, batch_no, expire_date, stock_count, storage, remark): 新增药品。 sql INSERT INTO medicines (name, generic_name, category, dosage_form, spec, manufacturer, batch_no, expire_date, stock_count, storage, remark) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) cur conn.execute(sql, ( name, generic_name, category, dosage_form, spec, manufacturer, batch_no, expire_date, stock_count, storage, remark )) conn.commit() return cur.lastrowid def list_medicines(conn, keywordNone): 按关键字查询药品支持名称、厂家、分类模糊搜索。 if keyword: sql SELECT * FROM medicines WHERE name LIKE ? OR generic_name LIKE ? OR manufacturer LIKE ? OR category LIKE ? ORDER BY expire_date ASC like_keyword f%{keyword}% params (like_keyword, like_keyword, like_keyword, like_keyword) else: sql SELECT * FROM medicines ORDER BY expire_date ASC params () return conn.execute(sql, params).fetchall() def get_medicine_by_id(conn, medicine_id): 根据主键查询药品详情。 sql SELECT * FROM medicines WHERE id ? return conn.execute(sql, (medicine_id,)).fetchone() def update_stock(conn, medicine_id, new_stock): 更新库存数量。 sql UPDATE medicines SET stock_count ?, updated_at datetime(now, localtime) WHERE id ? conn.execute(sql, (new_stock, medicine_id)) conn.commit() def soft_delete_medicine(conn, medicine_id): 物理删除药品及关联的用药记录。 sql DELETE FROM medicines WHERE id ? conn.execute(sql, (medicine_id,)) conn.commit() def check_expiring(conn, days30): 检查临期药品days 为剩余天数阈值。 today date.today().isoformat() sql SELECT *, julianday(expire_date) - julianday(?) AS remain_days FROM medicines WHERE julianday(expire_date) - julianday(?) ? ORDER BY remain_days ASC return conn.execute(sql, (today, today, days)).fetchall()这里用了julianday这个 SQLite 函数计算两个日期相差的天数。julianday(2026-09-30) - julianday(2025-01-01)会返回相差天数。这个写法简单直接适合判断有效期。4.2 日期解析辅助函数用户的输入习惯很难统一封装一个日期解析函数很有必要# 文件路径models.py追加 import re def normalize_expire_date(raw: str) - str: 将手工输入的日期格式统一为 YYYY-MM-DD。 支持 2026-09-01、2026.09、2026/09/30 等格式。 raw raw.strip() m re.match(r^(\d{4})[.\-/年](\d{1,2})[.\-/月](\d{1,2})日?$, raw) if m: year, month, day int(m.group(1)), int(m.group(2)), int(m.group(3)) return f{year:04d}-{month:02d}-{day:02d} m2 re.match(r^(\d{4})[.\-/年](\d{1,2})$, raw) if m2: year, month int(m2.group(1)), int(m2.group(2)) # 补当月最后一天 if month 12: last_day 31 else: next_month datetime(year, month 1, 1) last_day (next_month - __import__(datetime).timedelta(days1)).day return f{year:04d}-{month:02d}-{last_day:02d} raise ValueError(f无法解析日期格式: {raw})这段逻辑不复杂但很实用。例如用户输入“2026.09”程序会解析为 2026 年 9 月 30 日。这样做的好处是药品包装只写“有效期至2026.09”时我们按当月最后一天做保守处理不会高估有效期。4.3 命令行交互入口命令行入口用 Python 标准库的argparse实现支持以下子命令add新增药品list列出药品expiring检查临期药品use记录一次用药stock调整库存# 文件路径cli.py import argparse import sys import db import models def cmd_add(args): conn db.get_connection() try: expire_date models.normalize_expire_date(args.expire_date) except ValueError as e: print(f[错误] {e}) sys.exit(1) new_id models.add_medicine( conn, nameargs.name, generic_nameargs.generic_name, categoryargs.category, dosage_formargs.dosage_form, specargs.spec, manufacturerargs.manufacturer, batch_noargs.batch_no, expire_dateexpire_date, stock_countargs.stock_count, storageargs.storage, remarkargs.remark, ) print(f[成功] 已添加药品ID {new_id}) def cmd_list(args): conn db.get_connection() rows models.list_medicines(conn, keywordargs.keyword) if not rows: print([提示] 当前没有符合条件的药品记录。) return print(f{ID:4} {药品名称:16} {剂型:10} {规格:18} {库存:6} {有效期:12}) print(- * 80) for row in rows: print(f{row[id]:4} {row[name]:16} {row[dosage_form]:10} f{row[spec]:18} {row[stock_count]:6} {row[expire_date]:12}) def cmd_expiring(args): conn db.get_connection() rows models.check_expiring(conn, daysargs.days) if not rows: print(f[提示] 未来 {args.days} 天内没有临期药品。) return print(f[提示] 未来 {args.days} 天内到期或已过期药品如下) for row in rows: remain row[remain_days] if remain 0: status 已过期 elif remain 0: status 今天到期 else: status f剩余 {int(remain)} 天 print(fID{row[id]} {row[name]} 批号{row[batch_no]} 有效期{row[expire_date]} [{status}]) def cmd_use(args): conn db.get_connection() medicine models.get_medicine_by_id(conn, args.medicine_id) if not medicine: print(f[错误] 药品 ID{args.medicine_id} 不存在。) sys.exit(1) sql INSERT INTO usage_records (medicine_id, user_name, dosage, taken_at, note) VALUES (?, ?, ?, ?, ?) taken_at args.taken_at or __import__(datetime).datetime.now().isoformat(timespecminutes) conn.execute(sql, (args.medicine_id, args.user_name, args.dosage, taken_at, args.note)) conn.commit() print(f[成功] 已记录用药{medicine[name]}用药人{args.user_name}) def cmd_stock(args): conn db.get_connection() medicine models.get_medicine_by_id(conn, args.medicine_id) if not medicine: print(f[错误] 药品 ID{args.medicine_id} 不存在。) sys.exit(1) models.update_stock(conn, args.medicine_id, args.stock) print(f[成功] 药品 {medicine[name]} 库存已更新为 {args.stock}) def build_parser(): parser argparse.ArgumentParser(description家庭药品信息管理工具) subparsers parser.add_subparsers(destcommand) parser_add subparsers.add_parser(add, help新增药品) parser_add.add_argument(--name, requiredTrue, help商品名) parser_add.add_argument(--generic-name, default, help通用名) parser_add.add_argument(--category, default中成药, help分类) parser_add.add_argument(--dosage-form, default, help剂型) parser_add.add_argument(--spec, default, help规格) parser_add.add_argument(--manufacturer, default, help生产企业) parser_add.add_argument(--batch-no, default, help生产批号) parser_add.add_argument(--expire-date, requiredTrue, help有效期日期如 2026-09-30) parser_add.add_argument(--stock-count, typeint, default0, help库存数量) parser_add.add_argument(--storage, default, help存储条件) parser_add.add_argument(--remark, default, help备注) parser_list subparsers.add_parser(list, help查询药品列表) parser_list.add_argument(--keyword, default, help按名称/厂家/分类搜索) parser_expiring subparsers.add_parser(expiring, help查看临期药品) parser_expiring.add_argument(--days, typeint, default30, help剩余天数阈值) parser_use subparsers.add_parser(use, help记录用药) parser_use.add_argument(--medicine-id, typeint, requiredTrue, help药品 ID) parser_use.add_argument(--user-name, requiredTrue, help用药人) parser_use.add_argument(--dosage, default, help用量) parser_use.add_argument(--taken-at, default, help用药时间) parser_use.add_argument(--note, default, help备注) parser_stock subparsers.add_parser(stock, help调整库存) parser_stock.add_argument(--medicine-id, typeint, requiredTrue, help药品 ID) parser_stock.add_argument(--stock, typeint, requiredTrue, help新的库存数量) return parser def main(): parser build_parser() args parser.parse_args() if args.command is None: parser.print_help() sys.exit(0) if args.command add: cmd_add(args) elif args.command list: cmd_list(args) elif args.command expiring: cmd_expiring(args) elif args.command use: cmd_use(args) elif args.command stock: cmd_stock(args) if __name__ __main__: main()这段代码把不同命令的处理逻辑拆成独立函数便于阅读和测试。命令行工具的优点是轻量、不依赖图形界面通过 SSH 远程操作也很方便。4.4 运行与验证先初始化数据库python -c import db; db.init_db(); print(数据库初始化成功)添加一条“藿香正气水”的示例数据python cli.py add \ --name 藿香正气水 \ --generic-name 藿香正气水 \ --category 中成药/解表剂 \ --dosage-form 酊剂 \ --spec 10ml*10支 \ --manufacturer 示例药业 \ --batch-no 20250101 \ --expire-date 2026.09 \ --stock-count 3 \ --storage 密封置阴凉干燥处 \ --remark 含乙醇对酒精敏感者慎用再添加一盒软胶囊python cli.py add \ --name 藿香正气软胶囊 \ --generic-name 藿香正气软胶囊 \ --category 中成药/解表剂 \ --dosage-form 软胶囊剂 \ --spec 0.45g*24粒 \ --manufacturer 示例药业 \ --batch-no 20250315 \ --expire-date 2027-03-14 \ --stock-count 2 \ --storage 密封置阴凉干燥处 \ --remark 温水送服查询药品列表python cli.py list预期输出类似ID 药品名称 剂型 规格 库存 有效期 ---------------------------------------------------------------------------- 1 藿香正气水 酊剂 10ml*10支 3 2026-09-30 2 藿香正气软胶囊 软胶囊剂 0.45g*24粒 2 2027-03-14查看临期药品python cli.py expiring --days 365如果当前时间是 2026 年 8 月第一条记录就会提示临期因为距离 2026-09-30 不足 365 天。记录一次用药python cli.py use --medicine-id 1 --user-name 小李 --dosage 一次10ml --taken-at 2025-06-01T12:00:00 --note 饭后服用调整库存python cli.py stock --medicine-id 1 --stock 2运行这一套流程后数据库里就有了完整的药品主数据和用药历史。5. 扩展导出 Excel 报表命令行查看适合快速查询但向家人汇报药箱情况或者打印备份时Excel 更直观。下面用 pandas 实现导出功能。# 文件路径export_excel.py import pandas as pd import db def export_to_excel(output_pathmedicine_report.xlsx): conn db.get_connection() medicines_df pd.read_sql_query( SELECT id, name, generic_name, category, dosage_form, spec, manufacturer, batch_no, expire_date, stock_count, storage, remark FROM medicines ORDER BY expire_date ASC, conn, ) usage_df pd.read_sql_query( SELECT u.id, m.name AS medicine_name, u.user_name, u.dosage, u.taken_at, u.note FROM usage_records u LEFT JOIN medicines m ON u.medicine_id m.id ORDER BY u.taken_at DESC, conn, ) with pd.ExcelWriter(output_path, engineopenpyxl) as writer: medicines_df.to_excel(writer, sheet_name药品列表, indexFalse) usage_df.to_excel(writer, sheet_name用药记录, indexFalse) print(f[成功] 报表已导出{output_path}) print(f药品记录数{len(medicines_df)}) print(f用药记录数{len(usage_df)}) if __name__ __main__: export_to_excel()运行导出python export_excel.py这样就能生成一份本地 Excel 报表。pd.read_sql_query直接读取 SQLite 查询结果不需要手动拼接数据代码也简洁。这里要提醒一下pandas是重依赖如果只是日常查询不一定需要安装。可以把导出功能拆成独立脚本只在需要时使用。6. 常见问题与排查思路在实际运行过程中可能会遇到下面这些常见问题。问题现象常见原因解决思路运行时报sqlite3.OperationalError: no such table: medicines数据库文件存在但还没有执行建表脚本先执行python -c import db; db.init_db()初始化表结构插入中文药品名后控制台乱码Windows 终端编码不是 UTF-8在命令行执行chcp 65001切换到 UTF-8 代码页后再运行日期格式被识别错误输入了2026.09这类不完整格式程序内置解析函数会自动补全但必须确认统一为 YYYY-MM-DD 存储julianday计算结果为 NULLexpire_date字段插入了非日期文本用SELECT expire_date FROM medicines检查数据修复格式库存变成负数更新库存时没有做非空校验在cmd_stock中校验args.stock 0删除药品后旧用药记录还在外键约束未开启确保连接后执行PRAGMA foreign_keys ON数据库文件体积异常增大高频写操作积累了 WAL 日志正常备份后执行VACUUM压缩数据库排查时统一思路先查数据再查代码。很多看起来是程序逻辑的问题本质上都是脏数据导致的。比如有效期字段混入了“见包装”这种文本日期函数自然算不出结果。7. 最佳实践与工程建议7.1 药品数据字段规范药品名称建议使用商品名 通用名双字段。商品名是包装上的醒目名称通用名是国家批准的规范名称。这样做的好处是搜索时可以用任意一个名称命中。例如用户输入“藿藿”可能匹配不到但输入“藿香正气水”能精确命中而输入“藿香正气”能通过模糊搜索查到所有剂型。剂型字段单独存储不要拼在名称里。因为“藿香正气水”和“藿香正气口服液”虽然名称相近但剂型完全不同用量和禁忌也不同分开存储更利于后续筛选。批号字段不要省略。同一款药品可能因为不同批次导致有效期不同。如果只存药品名有效期提醒会出错。7.2 日期与时间处理所有日期统一使用 ISO 8601 格式存储也就是YYYY-MM-DD。这个格式的好处是字符串排序和日期排序结果一致直接ORDER BY expire_date就能得到正确的有效期顺序。用药时间建议使用带时分秒的完整时间戳比如2025-06-01T12:00:00。后续如果要分析什么时间段用药频率高这部分数据就有价值。7.3 安全边界这个工具定位是本地单机应用数据保存在本地数据库文件。第一不要轻易把数据库文件放到公网目录避免药品、家庭成员健康信息泄露。第二如果后续要扩展成 Web 服务必须加认证和授权不要裸奔在公网。第三数据库文件要定期备份。SQLite 备份最简单的方式是直接复制.db文件但建议在应用空闲时备份避免数据不一致。最好的做法是用 SQLite 自带的在线备份接口import sqlite3 source sqlite3.connect(data/medicine.db) target sqlite3.connect(backup/medicine_backup.db) source.backup(target) target.close() source.close()这段代码可以放到定时任务里每周执行一次。7.4 生产环境注意事项如果把这套思路扩展到团队内部或生产环境有几个地方要提前考虑数据库并发。SQLite 支持多读单写高并发写入会报database is locked。如果需要多人同时写应该迁移到 PostgreSQL 或 MySQL。数据备份。生产环境必须有自动备份和恢复演练不能只在出问题时才想起备份。权限控制。药品数据可能涉及健康隐私数据库文件、服务器文件权限都要收紧。日志记录。每一次库存变更、用药记录都应有审计日志方便回查。7.5 代码可维护性命令行工具虽然简单但代码分层要清晰。db.py只负责连接models.py只负责业务操作cli.py只负责参数解析和用户交互。这样后续想增加 Web 前端只需要复用models.py的函数不用动数据库逻辑。单元测试也建议补上至少覆盖日期解析和有效期计算这两个核心逻辑。# 文件路径test_models.py from datetime import date import db import models def test_normalize_expire_date(): assert models.normalize_expire_date(2026.09) 2026-09-30 assert models.normalize_expire_date(2026/09/01) 2026-09-01 assert models.normalize_expire_date(2026年12月) 2026-12-31 def test_check_expiring(): db.init_db() conn db.get_connection() models.add_medicine( conn, name测试药品, generic_name测试, category测试, dosage_form片剂, spec1片, manufacturer测试厂, batch_noT001, expire_datedate.today().isoformat(), stock_count1, storage阴凉, remark, ) rows models.check_expiring(conn, days30) assert len(rows) 1测试可以保证日期解析和有效期提醒两个最容易出错的部分始终符合预期。8. 下一步可以怎么扩展到这里一个以“藿藿”为案例对象的家庭药品管理工具已经能正常使用了。你可以直接把药品信息录入替换成本文示例数据就能管理真实的家庭药箱。如果还想继续深入下面是几个可扩展的方向第一做 Web 界面。用 Flask 或 FastAPI 包一层 HTTP 接口再用一个简单的前端页面展示药品列表和临期提醒让家里老人也能看懂。第二接入扫码识别。药品包装上通常有条码用扫码枪或手机摄像头读取条码再对接公开药品数据库可以自动带出药品名称、规格和厂家减少手工录入。第三加日历提醒。把临期药品和用药计划同步到手机日历可以实现自动化提醒不再依赖人工查看命令行。第四做家庭多人协同。如果家庭成员都有用药记录需求可以考虑把数据库迁移到云端数据库同时增加登录和权限控制。最后提醒一句工具只是辅助药品使用一定要以说明书和医生建议为准。技术能帮我们把信息管好但不能替代专业判断。你可以先从输入家里的常备药开始把这个工具跑起来再根据需要逐步加功能。动手实践永远比收藏代码更有价值。
返回列表