You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台Kivy/Python开发:SQLite数据库更新与用户数据留存问询

解决方案:Android Kivy/Python 应用SQLite数据库更新与数据留存

核心原则

永远不要直接修改安装目录下的数据库文件(更新时会被覆盖),所有用户数据必须存储在应用私有存储目录(Kivy中可通过user_data_dir获取),通过数据库版本管理+迁移脚本实现更新,确保首次启动新版本时自动执行结构升级。


具体实现步骤

1. 数据库文件的初始化与存储路径

  • 初始数据库模板(仅含表结构,无用户数据)放在应用的资源目录中,作为安装包的一部分。
  • 应用首次启动时,将模板数据库复制到user_data_dir(私有存储);后续启动直接读取私有存储中的数据库文件,避免被更新覆盖。

2. 数据库版本管理

使用SQLite内置的PRAGMA user_version来记录当前数据库结构版本,无需额外创建版本表:

  • 在代码中定义目标版本号(比如TARGET_DB_VERSION = 2),每次更新数据库结构时递增该值。
  • 应用启动时,读取数据库的当前版本号,对比目标版本,执行对应迁移操作。

3. 版本迁移逻辑(首次启动更新)

针对每个版本的结构变化,编写对应的迁移脚本,确保操作幂等(重复执行不会出错),比如新增字段、添加表等。


Kivy/Python 代码示例

获取数据库路径与初始化

from kivy.app import App
import os
import shutil
import kivy.resources
import sqlite3

class MyApp(App):
    def build(self):
        # 获取私有存储中的数据库路径
        self.db_path = os.path.join(self.user_data_dir, "app.db")
        # 获取安装包内的初始数据库模板路径
        initial_db = kivy.resources.resource_find("initial.db")

        # 首次启动:复制模板数据库到私有存储
        if not os.path.exists(self.db_path):
            shutil.copy(initial_db, self.db_path)
        
        # 连接数据库并执行迁移
        self.conn = sqlite3.connect(self.db_path)
        self._migrate_database()
        # 后续UI初始化...
        return YourMainWidget()

版本检查与迁移实现

def _get_db_version(self):
        cursor = self.conn.cursor()
        cursor.execute("PRAGMA user_version")
        return cursor.fetchone()[0]
    
    def _set_db_version(self, version):
        cursor = self.conn.cursor()
        cursor.execute(f"PRAGMA user_version = {version}")
        self.conn.commit()
    
    def _migrate_database(self):
        current_version = self._get_db_version()
        target_version = 2  # 每次更新结构时递增这个值

        # 从版本0(首次安装)升级到版本1:初始化基础表
        if current_version < 1:
            cursor = self.conn.cursor()
            # 幂等创建表,避免重复执行报错
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS user_generated_data (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    content TEXT NOT NULL,
                    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
                )
            """)
            self._set_db_version(1)
            current_version = 1
        
        # 从版本1升级到版本2:新增字段
        if current_version < 2:
            cursor = self.conn.cursor()
            # SQLite 3.35.0+支持IF NOT EXISTS,适配低版本可先检查字段是否存在
            cursor.execute("ALTER TABLE user_generated_data ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
            self._set_db_version(2)

实用建议

  • 迁移操作幂等性:所有迁移SQL都要确保重复执行不会报错,比如用CREATE TABLE IF NOT EXISTS、ADD COLUMN IF NOT EXISTS(注意低版本SQLite兼容性,若需适配旧系统,可先查询表结构判断字段是否存在)。
  • 自动备份:执行迁移前,自动复制当前数据库文件为备份(比如app.db.bak),避免迁移失败导致数据丢失。
  • 测试迁移流程:在发布更新前,模拟不同版本的数据库(比如版本1的用户数据),测试迁移到新版本是否正常,确保用户数据完整。
  • 避免直接修改模板库:安装包内的初始数据库仅作为结构模板,永远不要写入用户数据,所有读写操作都指向私有存储的数据库。

内容的提问来源于stack exchange,提问作者Compilererror

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:54:26