【问题标题】:How do I make and parse a raw SQL query with Diesel?如何使用 Diesel 生成和解析原始 SQL 查询?
【发布时间】:2021-01-03 08:19:57
【问题描述】:

我正在使用 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>,
            name -> Text,
            country -> Text,
        }
    }
}

use self::schema::organization;

#[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> {
         sql_query("SELECT id, name, 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)这一行呢?
  • 哦,哇,就是这么简单……我想多了。感谢您的帮助,请回答问题,我会接受!
  • 这并不能回答您的问题。它只会解决您的问题。

标签: mysql rust rust-diesel


【解决方案1】:

要解决您的问题,您可以删除 .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`

这很容易解决:按照编译器的建议执行操作,并删除前面的 &amp; 引用,以便您调用 .load(&amp;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 结构。 Diesel 为此提供了 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()
    }
}

【讨论】:

    猜你喜欢
    • 2023-01-14
    • 2017-01-15
    • 2020-10-11
    • 2014-02-15
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多