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

Rust构建web应用报sqlite3多包链接错误,该选择哪个版本的rusqlite

问题根源

报错的核心原因是你同时引入了两套不同的SQLite原生绑定依赖:

  • 你手动引入的rusqlite 0.23版本依赖libsqlite3-sys v0.18.0链接原生sqlite3库
  • 你引入的r2d2-sqlite3包底层依赖旧版本的sqlite3 crate,对应的sqlite3-sys v0.12.0也会链接原生sqlite3库
    Rust的cargo规则不允许同一个原生库被多个包重复链接,因此触发了该报错。
修复方案

不要使用已经停止维护的r2d2-sqlite3包,直接使用rusqlite官方内置的r2d2连接池集成功能即可,修改如下:

1. 修改Cargo.toml配置

删掉r2d2-sqlite3依赖,给rusqlite启用r2d2特性:

[package]
name = "todo"
version = "0.1.0"
edition = "2018"

[dependencies]
actix-web = "4.0.0-beta.3"
actix-rt = "2.2.0"
thiserror = "1.0.29"
askama = "0.10.5"
rusqlite = { version = "0.23", features = ["bundled", "r2d2"] }
r2d2 = "0.8.9"

2. 修改main.rs对应代码

调整连接池管理器的导入路径,同时删除conn.execute后多余的expect调用(?已经完成了错误抛出,返回的执行行数不需要再unwrap):

use actix_web::{get, App, HttpResponse, HttpServer, ResponseError};
use thiserror::Error;
use askama::Template;
use r2d2::Pool;
// 修改导入路径为rusqlite内置的r2d2管理器
use rusqlite::r2d2::SqliteConnectionManager;
use rusqlite::params;

struct TodoEntry {
    id: u32,
    text: String,
}

#[derive(Template)]
#[template(path = "index.html")]
struct IndexTemplate {
    entries: Vec<TodoEntry>,
}

#[derive(Error, Debug)]
enum MyError {
    #[error("Failed to render HTML")]
    AskamaError(#[from] askama::Error),
}

impl ResponseError for MyError {}

#[get("/")]
async fn index() -> Result<HttpResponse, MyError> {

    let mut entries = Vec::new();

    entries.push(TodoEntry {
        id: 1,
        text: "First entry".to_string(),
    });
    entries.push(TodoEntry {
        id: 2,
        text: "Second entry".to_string(),
    });

    let html = IndexTemplate { entries };
    let response_body = html.render()?;

    Ok(HttpResponse::Ok()
        .content_type("text/html")
        .body(response_body))
}

#[actix_rt::main]
async fn main() -> Result<(), actix_web::Error> {

    let manager = SqliteConnectionManager::file("todo.db");
    let pool = Pool::new(manager).expect("Failed to initialize the connection pool.");
    let conn = pool
        .get()
        .expect("Failed to get the connection from the pool.");
    conn.execute(
        "CREATE TABLE IF NOT EXISTS todo (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        text TEXT NOT NULL
        )",
        params![],
    )?;

    HttpServer::new(move || App::new().service(index))
        .bind("127.0.0.1:8080")?
        .run()
        .await?;
    Ok(())
}

修改后执行cargo clean清理之前的构建缓存,再运行cargo run即可正常编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:18:04