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

时间:2017-04-07 02:25:41

标签: mysql rust rust-diesel

我使用连接池系统设置了一个系统,该系统利用dieselr2d2r2d2-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种语言和几个应用程序主动使用而没有问题,所以我对此表示怀疑。

1 个答案:

答案 0 :(得分:3)

编辑:已在最新版本的相关包装箱中修复此问题。

事实证明r2d2-dieselis 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,它应该作为替代品。