使用 Diesel、r2d2 和 r2d2-diesel 查询数据库时出错

Posted

技术标签:

【中文标题】使用 Diesel、r2d2 和 r2d2-diesel 查询数据库时出错【英文标题】:Error querying database using Diesel, r2d2, and r2d2-diesel 【发布时间】:2017-09-02 06:43:45 【问题描述】:

我使用连接池系统设置了一个系统,该系统利用diesel、r2d2 和r2d2-diesel 作为我的 Web 应用程序的 API 主机。我一直关注这个blog post 作为帮助我进行设置的基础。但是,我已经对我的数据库后端切换到 mysql 进行了修改;我已经添加了必要的柴油功能,并认为这不会成为问题。

这是我用来设置连接池的代码(与博文中的非常相似):

use diesel::prelude::*;
use diesel::mysql::MysqlConnection;
use r2d2:: GetTimeout, Pool, PooledConnection, Config ;
use r2d2_diesel::ConnectionManager;

pub struct DB(PooledConnection<ConnectionManager<MysqlConnection>>);

impl DB 
    pub fn conn(&self) -> &MysqlConnection 
        &*self.0
    


pub fn create_db_pool() -> Pool<ConnectionManager<MysqlConnection>> 
    let config = Config::default();
    let manager = ConnectionManager::<MysqlConnection>::new(format!("", DB_CREDENTIALS));
    Pool::new(config, manager).expect("Failed to create pool.")

我在设置数据库接口系统的过程中遇到了一个问题。当我通过柴油对数据库进行任何查询时,出现以下错误:Err(DatabaseError(__Unknown, "Commands out of sync; you can\'t run this command now"))

我进行了一些研究,似乎在发送另一个查询之前尚未读取之前的查询时会发生此错误,这使我相信这可能是库错误。我检查了 MySQL 查询日志,除了在连接池中创建连接的查询之外,我没有看到任何查询。

我已将我的错误缩减为一个测试用例。以下响应我上面粘贴的错误消息:

/// Make sure we can run basic queries on the database using a connection pool
#[test]
fn basic_queries() 
    use diesel::connection::SimpleConnection;

    let mut pool = create_db_pool();
    let mut conn = pool.get().unwrap();
    let res = conn.batch_execute("SELECT 1");
    println!(":?", res);

运行如下查询会产生相同的错误消息,但要简化为单个测试用例要困难得多:

let query = diesel::insert(&beatmap).into(schema::beatmaps::dsl::beatmaps);
// println!(":?", query);
print_sql!(query);
let conn: &MysqlConnection = &*client.pool.get().expect("Unable to get connection from pool");
let res = query.execute(conn);

我想这是我的一个实现错误,但这可能与我的数据库配置有关吗?我用于开发的数据库正在被超过 3 种语言和多个应用程序积极使用,没有问题,所以我对此表示怀疑。

【问题讨论】:

这似乎确实是 Diesel 库和 r2d2-diesel 的问题:github.com/diesel-rs/diesel/issues/728 【参考方案1】:

编辑:此问题已在相关板条箱的最新版本中得到修复。

原来r2d2-diesel 库is currently broken for MySQL。运行状况检查会进行查询,但从不读取结果,这会打乱 MySQL 命令对用户进行的查询的排序。

我创建了一个解决问题的 r2d2-diesel 存储库的分支。它不是作为长期解决方案而设计的,仅适用于 MySQL 客户端。如果您想使用它,请将以下内容添加到您的Cargo.toml

r2d2-diesel-mysql =  git = "https://github.com/Ameobea/r2d2-diesel" 

在您的代码库中将r2d2_diesel 的所有实例更改为r2d2_diesel_mysql,它应该可以作为替代品使用。

【讨论】:

已发布对此的修复。

以上是关于使用 Diesel、r2d2 和 r2d2-diesel 查询数据库时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 r2d2 在 rust/diesel 应用程序中实现连接池

IfcCartesianTransformationOperator2D

CSP-S 模拟 R2D2 总结

使用 Diesel 执行插入或更新

如何使用 Diesel 和 SQLite 获取新创建值的 id?

如何使用 Diesel 和 SQLite 获取新创建值的 id?