如何使用Diesel进行并解析原始SQL查询?

问题描述

我正在使用Rocket框架测试Rust。对于数据库,我正在使用Diesel与我的MysqL数据库进行交互。

下面举几个例子,很多事情发生在幕后。我有一个运行MysqL数据库,并在其中填充了原始表。

以下代码有效:

use diesel::{prelude::*};

mod schema {
    table! {
        organization {
            id -> Nullable<Integer>,name -> Text,country -> Text,}
    }
}

use self::schema::organization;
use self::schema::organization::dsl::{organization as all_orgs};

#[table_name="organization"]
#[derive(Serialize,Deserialize,Queryable,Insertable,Debug,Clone)]
pub struct Organization {
    pub id: Option<i32>,pub name: String,pub country: String
}

impl Organization {
    pub fn all(conn: &MysqLConnection) -> Vec<Organization> {
        all_orgs.order(organization).load::<Organization>(conn).unwrap()
    }
}

但是,我不需要订购任何东西。实际上,我只想以SELECT id,name,country FROM organization的形式进行原始查询,并称之为一天。

查看Diesel documentation之后,我尝试了以下操作,并发现了名为sql_query的东西。

我的代码现在看起来像:

use diesel::{prelude::*,sql_query};

mod schema {
    table! {
        organization {
            id -> Nullable<Integer>,}
    }
}

use self::schema::organization;

#[table_name="organization"]
#[derive(Serialize,pub country: String
}

impl Organization {
    pub fn all(conn: &MysqLConnection) -> Vec<Organization> {
         sql_query("SELECT id,country FROM organization")
            .load(&conn).unwrap()
    }
}

但是,在对此更改进行cargo run时,我面临着:

error[E0277]: the trait bound `&diesel::MysqLConnection: diesel::Connection` is not satisfied
  --> src/org.rs:26:19
   |
26 |             .load(&conn).unwrap()
   |                   -^^^^
   |                   |
   |                   the trait `diesel::Connection` is not implemented for `&diesel::MysqLConnection`
   |                   help: consider removing the leading `&`-reference
   |
   = help: the following implementations were found:
             <diesel::MysqLConnection as diesel::Connection>
   = note: required because of the requirements on the impl of `LoadQuery<&diesel::MysqLConnection,_>` for `sqlQuery`

error[E0277]: the trait bound `Organization: QueryableByName<_>` is not satisfied
  --> src/org.rs:26:14
   |
26 |             .load(&conn).unwrap()
   |              ^^^^ the trait `QueryableByName<_>` is not implemented for `Organization`
   |
   = note: required because of the requirements on the impl of `LoadQuery<&diesel::MysqLConnection,Organization>` for `sqlQuery`

在给定输入参数和所需输出的情况下,如何允许我执行原始SQL查询并从函数正确解析它,我如何满足这些错误

解决方法

要解决您的问题,您可以删除.order(organization)以避免执行排序。

要回答明确提出的问题:错误消息提到了两个问题:

error[E0277]: the trait bound `&diesel::MysqlConnection: diesel::Connection` is not satisfied
  --> src/org.rs:26:19
   |
26 |             .load(&conn).unwrap()
   |                   -^^^^
   |                   |
   |                   the trait `diesel::Connection` is not implemented for `&diesel::MysqlConnection`
   |                   help: consider removing the leading `&`-reference
   |
   = help: the following implementations were found:
             <diesel::MysqlConnection as diesel::Connection>
   = note: required because of the requirements on the impl of `LoadQuery<&diesel::MysqlConnection,_>` for `SqlQuery`

该问题很容易解决:按照编译器的建议进行操作,并删除对&的调用的前导.load(&conn)引用。

error[E0277]: the trait bound `Organization: QueryableByName<_>` is not satisfied
  --> src/org.rs:26:14
   |
26 |             .load(&conn).unwrap()
   |              ^^^^ the trait `QueryableByName<_>` is not implemented for `Organization`
   |
   = note: required because of the requirements on the impl of `LoadQuery<&diesel::MysqlConnection,Organization>` for `SqlQuery`

这一点指出了一个实际问题,即不允许在您的Organization结构中加载结果。需要告知Diesel如何从查询响应中构造Organization结构。柴油为此提供了2个特征:

  • Queryable,用于从类型安全查询的结果(===使用柴油提供的dsl构建查询,以便在编译时对其进行检查)的结果中构造结构。 `
  • QueryableByName根据非类型安全查询(因此基本上是通过diesel::sql_query执行的查询)的结果构造一个结构

如错误消息所述,您的结构未实现QueryableByName,这是在该结构中加载diesel::sql_query的结果所必需的。您需要实现此特征。最简单的选择是使用Diesel提供的derive

代码的固定版本如下:

use diesel::{prelude::*,sql_query};

mod schema {
    table! {
        organization {
            id -> Nullable<Integer>,name -> Text,country -> Text,}
    }
}

use self::schema::organization;

#[table_name="organization"]
#[derive(Serialize,Deserialize,Queryable,QueryableByName,Insertable,Debug,Clone)]
pub struct Organization {
    pub id: Option<i32>,pub name: String,pub country: String
}

impl Organization {
    pub fn all(conn: &MysqlConnection) -> Vec<Organization> {
         sql_query("SELECT id,name,country FROM organization")
            .load(&conn).unwrap()
    }
}