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

Windows 10下SQLx+SQLite工作区相对路径配置问题解决

在Windows 10上绕过SQLx的SQLite相对路径问题

问题场景

我的工作区结构如下:

workspace/
  Cargo.toml
  .env

  base_dir/
    db.sqlite

  binary_crate/
    src/
      main.rs

VS Code中sqlx::query!宏被标红,悬停提示:

error returned from database: (code: 14) unable to open database file

进入binary_crate目录执行cargo sqlx prepare时,也会触发相同错误:

error: error returned from database: (code: 14) unable to open database file
  --> binary_crate\src\main.rs:21:20
   |
21 |           let user = sqlx::query!
...
28 | |         )
   | |_________^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)

这是SQLx处理CARGO_MANIFEST_DIR变量的已知问题导致的,之前尝试在.env中配置DATABASE_URL="sqlite://${CARGO_MANIFEST_DIR}/base_dir/db.sqlite",但没有效果。

绕过方案

方法1:使用绝对路径(临时应急)

直接在.env中写死数据库的绝对路径,注意Windows路径用正斜杠或转义反斜杠:

DATABASE_URL="sqlite://C:/path/to/your/workspace/base_dir/db.sqlite"
# 或
DATABASE_URL="sqlite://C:\\path\\to\\your\\workspace\\base_dir\\db.sqlite"

方法2:在工作区根目录执行prepare命令

不要进入binary_crate目录,回到workspace根目录执行:

cargo sqlx prepare --manifest-path binary_crate/Cargo.toml

此时SQLx会以工作区根目录为基准解析路径,能正确定位到数据库文件。

方法3:自定义环境变量替代CARGO_MANIFEST_DIR

  1. 在.env中定义工作区根目录变量:
WORKSPACE_ROOT="C:/path/to/your/workspace"
DATABASE_URL="sqlite://${WORKSPACE_ROOT}/base_dir/db.sqlite"
  1. 或者启动前动态设置(PowerShell示例):
$env:WORKSPACE_ROOT = (Get-Location).Path
cargo run --manifest-path binary_crate/Cargo.toml

方法4:代码中动态构建数据库路径

在main.rs中手动拼接路径,完全绕过SQLx宏的路径解析逻辑:

use std::path::PathBuf;

#[tokio::main]
async fn main() {
    // 从binary_crate目录向上回溯两级到工作区根目录
    let workspace_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .unwrap()
        .parent()
        .unwrap();
    let db_path = workspace_root.join("base_dir").join("db.sqlite");
    let database_url = format!("sqlite://{}", db_path.display());

    // 创建连接池并执行查询
    let pool = sqlx::SqlitePool::connect(&database_url).await.unwrap();
    let user = sqlx::query!("SELECT * FROM users LIMIT 1")
        .fetch_one(&pool)
        .await
        .unwrap();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:40:10