Appearance
Schema 迁移
灵动桌面框架使用 SQLite 的 PRAGMA user_version 实现简单可靠的 Schema 版本管理。
迁移机制
rust
// src-tauri/src/database/schema.rs
const CURRENT_VERSION: i32 = 1;
pub fn migrate(conn: &Connection) -> Result<(), AppError> {
let version: i32 = conn.pragma_query_value(
None, "user_version", |row| row.get(0)
)?;
if version < 1 {
migrate_v1(conn)?;
}
// if version < 2 {
// migrate_v2(conn)?;
// }
conn.pragma_update(None, "user_version", CURRENT_VERSION)?;
Ok(())
}
fn migrate_v1(conn: &Connection) -> Result<(), AppError> {
conn.execute_batch("
CREATE TABLE IF NOT EXISTS app_config (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT NOT NULL UNIQUE,
value TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
")?;
Ok(())
}添加新迁移
当需要修改数据库结构时:
- 递增
CURRENT_VERSION - 添加新的迁移函数
- 在
migrate()中添加版本检查
rust
const CURRENT_VERSION: i32 = 2;
pub fn migrate(conn: &Connection) -> Result<(), AppError> {
let version: i32 = conn.pragma_query_value(
None, "user_version", |row| row.get(0)
)?;
if version < 1 { migrate_v1(conn)?; }
if version < 2 { migrate_v2(conn)?; } // 新增
conn.pragma_update(None, "user_version", CURRENT_VERSION)?;
Ok(())
}
fn migrate_v2(conn: &Connection) -> Result<(), AppError> {
conn.execute_batch("
CREATE TABLE IF NOT EXISTS user_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
")?;
Ok(())
}迁移原则
- 只增不删 — 新版本只添加表或列,不删除已有结构
- 向后兼容 — 老数据在新 Schema 下仍然可用
- 顺序执行 — 迁移按版本号顺序执行
- 幂等性 — 使用
IF NOT EXISTS确保重复执行安全