首页 > 解决方案 > 我应该使用什么版本的 rusqlite?

问题描述

我正在学习 rust 语言。因此,我尝试使用 sqlite3 构建一个简单的 Web 应用程序。但它得到多个包链接错误。
我看到了这个错误的一些解决方案(例如this),但它们没有用。
原因似乎是版本规范rusqlite错误,但不知道正确的版本规范。
我应该如何配置cargo.toml

源代码在这里。
cargo.toml

[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 = "0.8.9"
r2d2-sqlite3 = "0.1.1"

main.rs

use actix_web::{get, App, HttpResponse, HttpServer, ResponseError};
use thiserror::Error;
use askama::Template;
use r2d2::Pool;
use r2d2_sqlite3::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![],
    )?
        .expect("Failed to create a table `todo`");

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

错误消息在这里。

error: multiple packages link to native library `sqlite3`, but a native library can be linked only once

package `libsqlite3-sys v0.18.0`
    ... which is depended on by `rusqlite v0.23.1`
    ... which is depended on by `todo v0.1.0 (/Users/******/Documents/IntelliJ project/Rust-project/todo)`
links to native library `sqlite3`

package `sqlite3-src v0.2.9`
    ... which is depended on by `sqlite3-sys v0.12.0`
    ... which is depended on by `sqlite3 v0.24.0`
    ... which is depended on by `r2d2-sqlite3 v0.1.1`
    ... which is depended on by `todo v0.1.0 (/Users/*****/Documents/IntelliJ project/Rust-project/todo)`
also links to native library `sqlite3`

标签: sqliterustrust-cargo

解决方案


您直接依赖rusqlite和使用r2d2-sqlite3which 本身依赖于rusqlite.

由于rusqlite绑定到本机库,因为消息表明您不能将两个版本的 rusqlite 链接到不同版本的 sqlite3(-sys),因此您需要确保使用与 r2d2 相同版本的 rusqlite。

如果您不打算在 Cargo 上发布,目前最简单的方法是将rusqlite的版本保留为通配符 ( "*"),这样依赖解析器将为您提供任何适用于r2d2-sqlite3. 否则你需要检查r2d2-sqlite3你正在使用的版本并匹配它。

顺便说一句... r2d2-sqlite3 0.1.1?那似乎已经超过 4 年了,当前版本似乎是0.18。我有点惊讶 r2d2 的作品,虽然我猜它的变化相对较小(0.8.0 是 4 年前,当前是 0.8.9)。虽然我不确定 r2d2 对 sqlite3 有什么用处,尤其是对于“一个简单的网络应用程序”。


推荐阅读