如何防止应用重部署更新时所用sqlite3数据库被替换
出现这个问题的核心原因是你把.db数据库文件放在了应用安装包的同步目录里,每次覆盖部署新版本时,构建流程会把整个安装目录的文件全量替换到设备上,旧的数据库自然会被打包进去的空库覆盖。以下是几个亲测可用的解决方法,个人用足够方便:
可行解决方案
方案1:将数据库存到应用持久化用户数据目录(一劳永逸推荐)
- 不管你用Kivy、BeeWare还是其他Python移动开发框架,系统都会给每个应用分配一个独立的用户数据存储目录,这个目录下的文件不会随应用覆盖安装、版本更新被清空,只有手动卸载应用时才会被系统删除。
- 操作逻辑非常简单:初始化sqlite连接时,不要用相对路径把db存在项目源码同级目录,先拿到这个持久化目录的绝对路径,再拼接db文件的完整路径做连接即可,示例代码如下:
import os import sqlite3 # 不同框架获取持久化目录的接口不同,不需要写原生代码 # Kivy用下面这行: # from kivy.app import App # data_dir = App.get_running_app().user_data_dir # BeeWare用下面这行: # data_dir = self.paths.data db_path = os.path.join(data_dir, "business_data.db") conn = sqlite3.connect(db_path)
- 第一次部署改完路径的版本时,可以加个简单判断:如果持久化目录下还没有db文件,就把安装包里带的初始模板db复制过去,后续所有业务读写都操作这个路径下的db即可,再也不会被部署覆盖。
方案2:部署时增加db备份回传逻辑(适合临时调试)
- 如果只是开发调试阶段不想改代码逻辑,可以在部署脚本里加两步操作:每次推送新构建的安装包到设备前,先把设备上现存的
.db文件拉到本地备份,等新包部署完成后,再把备份的db传回设备覆盖新生成的空库。 - 比如安卓调试用adb的话,也就是两行push/pull命令的事,缺点是每次部署都要多一步操作,长期用不如方案1省事。
方案3:补充轻量数据库迁移逻辑(适合长期使用)
- 如果后续会持续迭代应用功能、调整数据库结构,可以加个极简单的版本判断:在库里建个仅存配置项的系统表,存当前数据库的版本号,每次应用启动时先比对db版本和当前应用要求的版本,如果版本落后就自动执行写好的SQL语句,给旧库加新表、补字段,不需要直接替换整个db文件。
- 个人使用完全不需要引入Alembic这类重量级迁移框架,自己写判断逻辑也就十几行代码,足够用。
注意:不要把数据库文件存在应用缓存目录下,系统存储空间不足时会自动清理缓存目录的文件,大概率会丢数据。
内容的提问来源于stack exchange,提问作者Edric Antoine
相关产品推荐
相关产品推荐

