当前位置: 首页 > news >正文

边走边聊 Python 3.8:Chapter 12+1:MyKB 升级篇-用 SQLite 数据库彻底替换 JSON 存储

MyKB 升级篇:用 SQLite 数据库彻底替换 JSON 存储

MyKB笔记多了以后,JSON 文件读写越来越慢,搜索也卡。
今天我们直接升级,把notes.json彻底换成SQLite 数据库

为什么换 SQLite?

  • Python 3.8内置sqlite3模块(Win7 无需 pip 安装)
  • 查询速度提升 10 倍以上(支持索引)
  • 支持 SQL 语句,以后想加“按标签统计”“按日期范围”超级简单
  • 数据更安全(事务机制,意外断电也不会损坏)
  • 文件体积更小,自动归档更优雅

全部改动只集中在note_manager.py,其他文件几乎不用动!


1、项目结构小调整(只需加一个文件)

MyKB/ ├── main.py ├── config.py ├── note_manager.py ← 重点替换这个 ├── gui.py ├── utils.py ├── notes/ │ ├── mykb.db ← 新增的 SQLite 数据库文件(程序自动创建) │ └── archive/ ← 归档文件夹保持不变 ├── data/ ├── ...

2、完整替换后的 note_manager.py(直接覆盖)

# -*- coding: utf-8 -*-importsqlite3importosfromdatetimeimportdatetime,timedeltaimportjson# 只用于迁移旧数据fromconfigimportNOTES_DIR,ARCHIVE_DIRclassNoteManager:def__init__(self):self.db_path=os.path.join(NOTES_DIR,"mykb.db")self.conn=sqlite3.connect(self.db_path)self.conn.row_factory=sqlite3.Row# 让查询结果可以像字典一样访问self.create_table()self.migrate_from_json()# 首次运行时自动迁移旧 JSON 数据defcreate_table(self):"""创建笔记表 + 索引"""cursor=self.conn.cursor()cursor.execute(''' CREATE TABLE IF NOT EXISTS notes ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL, tags TEXT, -- 用逗号分隔存储 date TEXT NOT NULL ) ''')# 为搜索创建索引(速度飞起!)cursor.execute('CREATE INDEX IF NOT EXISTS idx_title ON notes(title)')cursor.execute('CREATE INDEX IF NOT EXISTS idx_content ON notes(content)')cursor.execute('CREATE INDEX IF NOT EXISTS idx_date ON notes(date)')self.conn.commit()defmigrate_from_json(self):"""只运行一次:把旧 notes.json 迁移到 SQLite"""json_path=os.path.join(NOTES_DIR,"notes.json")ifos.path.exists(json_path)andnotself.get_all_notes():print("正在迁移旧 JSON 数据到 SQLite...")withopen(json_path,"r",encoding="utf-8")asf:old_notes=json.load(f)fornoteinold_notes:tags_str=",".join(note.get("tags",[]))self.add_note(note["title"],note["content"],tags_str,note["date"])# 迁移完备份旧文件os.rename(json_path,json_path+".bak")print(f"迁移完成!共{len(old_notes)}条笔记,已备份为 notes.json.bak")defadd_note(self,title,content,tags="",date=None):"""新增笔记"""ifdateisNone:date=datetime.now().strftime("%Y-%m-%d %H:%M:%S")cursor=self.conn.cursor()cursor.execute(''' INSERT INTO notes (title, content, tags, date) VALUES (?, ?, ?, ?) ''',(title,content,tags,date))self.conn.commit()returncursor.lastrowiddefget_all_notes(self):"""获取所有笔记(用于界面列表)"""cursor=self.conn.cursor()cursor.execute("SELECT id, title, date FROM notes ORDER BY date DESC")return[dict(row)forrowincursor.fetchall()]defsearch(self,keyword):"""全文搜索(标题 + 内容 + 标签)"""keyword=f"%{keyword}%"cursor=self.conn.cursor()cursor.execute(''' SELECT id, title, date FROM notes WHERE title LIKE ? OR content LIKE ? OR tags LIKE ? ORDER BY date DESC ''',(keyword,keyword,keyword))return[dict(row)forrowincursor.fetchall()]defget_note_by_id(self,note_id):"""查看单条笔记详情"""cursor=self.conn.cursor()cursor.execute("SELECT * FROM notes WHERE id = ?",(note_id,))row=cursor.fetchone()returndict(row)ifrowelseNonedefauto_archive(self):"""自动归档 >30天的笔记(保持原有逻辑)"""threshold=(datetime.now()-timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S")cursor=self.conn.cursor()cursor.execute("SELECT * FROM notes WHERE date < ?",(threshold,))old_notes=[dict(row)forrowincursor.fetchall()]ifold_notes:fornoteinold_notes:archive_path=os.path.join(ARCHIVE_DIR,f"{note['id']}_{note['title'][:20]}.json")withopen(archive_path,"w",encoding="utf-8")asf:json.dump(note,f,ensure_ascii=False,indent=2)cursor.execute("DELETE FROM notes WHERE id = ?",(note["id"],))self.conn.commit()print(f"已归档{len(old_notes)}条笔记")defclose(self):"""程序退出时关闭连接"""self.conn.close()

3、其他文件只需微调(复制粘贴即可)

1. gui.py 中的小改动(替换对应函数)

# 在 KBApp 类里替换以下两个方法:defrefresh_list(self):foriinself.tree.get_children():self.tree.delete(i)notes=self.manager.get_all_notes()fornoteinnotes:self.tree.insert("","end",values=(note["id"],note["title"],note["date"]))defdo_search(self):kw=self.search_entry.get().strip()ifnotkw:self.refresh_list()returnresults=self.manager.search(kw)foriinself.tree.get_children():self.tree.delete(i)fornoteinresults:self.tree.insert("","end",values=(note["id"],note["title"],note["date"]))defview_note(self):sel=self.tree.selection()
http://www.jsqmd.com/news/703646/

相关文章:

  • 如何快速清理Android预装应用?Universal Android Debloater终极指南
  • 如何彻底告别网盘限速:8大主流网盘直链下载终极指南
  • 2026 年保温材料/高性能保温材料/防火保温材料厂家选择指南 - 海棠依旧大
  • 保姆级教程:在国产麒麟系统上从零搭建Samba共享文件夹(含防火墙和权限配置)
  • G-Helper技术解析:华硕笔记本硬件控制的开源解决方案
  • AI爬虫防护实战:从robots.txt到Nginx/Apache拦截配置详解
  • MeshCentral:开源自托管远程管理平台部署与实战指南
  • JSP 九大内置对象与 EL 表达式:告别 %% 脚本
  • 盘点2026年电机轴靠谱生产商,经验丰富、高精度厂家排名 - 工业品牌热点
  • 造相-Z-Image离线部署全攻略:断网也能用的AI绘画神器
  • 从CH340电路原理图到一次烧录成功:ESP32/Arduino下载电路保姆级调试笔记
  • 毕马威:低空经济蓄势腾飞开辟消费新蓝海报告 2026
  • Path of Building完整指南:5分钟掌握《流放之路》最强离线Build规划工具
  • 网格交易实战:用掘金量化回测中国神华,聊聊策略失效的边界与风控
  • Servlet 转发与重定向:大白话对比 + 代码实战
  • 三步实现突破性低延迟:DroidCam OBS插件技术解析与高性能配置方案
  • GD32/STM32单片机程序卡死在0xFFFFFFFE?别急着找野指针,先检查这个SystemInit里的隐藏配置
  • 5步掌握Vulkan GPU显存稳定性测试:memtest_vulkan完整实战指南
  • SuperPrompt:撬动大语言模型深度思考的元提示工程框架
  • 分析河南手拉葫芦厂家,手拉葫芦定制颜色哪家性价比高 - 工业品网
  • 终极指南:3步让Mac Finder完美预览所有视频格式,告别空白图标烦恼
  • 聊聊2026年洗衣机轴专业厂家,哪家售后服务好? - mypinpai
  • 华硕笔记本色彩异常终极修复指南:G-Helper免费解决方案
  • 告别手动重启!用Shell脚本自动搞定天翼网关4.0光猫(附TEWA-1006G等型号通用教程)
  • 从GUI到爬虫:盘点Python回调函数callback在5个真实项目里的妙用(避坑指南)
  • Kimi-CLI:命令行集成大模型,打造高效AI工作流
  • 洗衣机轴定制服务提供商哪家性价比高 - 工业设备
  • 2026年好用的IT人才外包公司推荐,京沪广深地区哪家口碑好 - 工业推荐榜
  • 大麦助手DamaiHelper终极指南:三分钟搞定演唱会抢票的完整教程
  • 别再只盯着CMOS了!手把手教你用LVDS搞定FPGA与高速ADC的‘远距离’通信(附PCB布线避坑指南)