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

如何修复Tauri-Rust结合Diesel与SQLite的数据库缓存问题?

解决方案

1. 修复数据库连接字符串错误

你修改连接时用了sqlite://{}?cache=none的格式,但Diesel的SQLite连接不需要sqlite://前缀,直接传入文件路径即可。正确禁用SQLite缓存的方式是通过连接配置或执行PRAGMA命令:

方式一:执行PRAGMA命令禁用缓存

use diesel::sqlite::SqliteConnection;
use diesel::Connection;

pub fn establish_connection(path: &str) -> SqliteConnection {
    let mut conn = SqliteConnection::establish(path)
        .unwrap_or_else(|_| panic!("Error connecting to database {}", path));
    
    // 执行SQL命令关闭缓存
    conn.execute("PRAGMA cache_size = 0; PRAGMA temp_store = MEMORY;")
        .expect("Failed to disable SQLite cache");
    
    conn
}

方式二:用Diesel连接配置设置参数

use diesel::sqlite::SqliteConnection;
use diesel::sqlite::SqliteConnectionOptions;
use diesel::Connection;

pub fn establish_connection(path: &str) -> SqliteConnection {
    let options = SqliteConnectionOptions::new()
        .filename(path)
        .pragma("cache_size", "0")
        .pragma("temp_store", "MEMORY");
    
    SqliteConnection::establish_with_config(options)
        .unwrap_or_else(|_| panic!("Error connecting to database {}", path))
}

2. 解决迁移脚本重复插入初始数据的问题

删除数据库文件后仍出现相同数据,核心原因是迁移脚本中每次执行都会插入初始数据,而非仅在表首次创建时执行。

修正迁移脚本逻辑

修改migrations/目录下的迁移文件,给插入语句添加条件判断,确保仅在数据不存在时插入:

-- 仅当表为空时插入初始数据
INSERT INTO pwn_contracts (name)
SELECT '初始合约1' WHERE NOT EXISTS (SELECT 1 FROM pwn_contracts);

INSERT INTO pwn_contracts (name)
SELECT '初始合约2' WHERE NOT EXISTS (SELECT 1 FROM pwn_contracts WHERE name = '初始合约2');

分离初始数据逻辑(可选)

如果不想每次重建数据库都插入初始数据,可将初始数据插入逻辑从迁移脚本中移出,放到应用启动时的条件判断里:

pub fn init_default_data(conn: &mut SqliteConnection) {
    use crate::schema::pwn_contracts;
    use diesel::insert_into;
    use diesel::select;
    use diesel::dsl::exists;

    // 检查是否已有数据,无数据则插入
    let has_data = select(exists(pwn_contracts::table))
        .get_result::<bool>(conn)
        .unwrap();
    
    if !has_data {
        insert_into(pwn_contracts::table)
            .values(&vec![
                (pwn_contracts::name.eq("初始合约1")),
                (pwn_contracts::name.eq("初始合约2")),
            ])
            .execute(conn)
            .unwrap();
    }
}

3. 确认Tauri开发模式下的数据库路径

Tauri开发模式中,应用数据目录可能和你手动删除的路径不一致,可打印实际路径确认:

pub fn contract_list(db_path: String) -> Vec<Contract> {
    println!("实际数据库路径: {}", db_path); // 打印路径,验证是否删除了正确文件
    let mut connection = establish_connection(&db_path);
    pwn_contracts::dsl::pwn_contracts
        .select(pwn_contracts::all_columns)
        .load::<Contract>(&mut connection)
        .expect("Loading contracts failed")
}

推荐使用Tauri提供的专属数据目录,避免路径混乱:

use tauri::api::path::data_dir;
use std::path::PathBuf;

fn get_db_path() -> String {
    let mut data_dir = data_dir().expect("获取数据目录失败");
    data_dir.push("你的应用名称");
    std::fs::create_dir_all(&data_dir).expect("创建数据目录失败");
    data_dir.push("app.db");
    data_dir.to_str().unwrap().to_string()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 10:13:11