Rust Diesel 原始 SQL 给出错误“`std::result::Result<Vec<T>,diesel::result::Error>` 所需的类型注释”

Posted

技术标签:

【中文标题】Rust Diesel 原始 SQL 给出错误“`std::result::Result<Vec<T>,diesel::result::Error>` 所需的类型注释”【英文标题】:Rust Diesel raw SQL gives error "type annotations needed for `std::result::Result<Vec<T>, diesel::result::Error>`" 【发布时间】:2021-04-28 09:19:21 【问题描述】:

我正在尝试使用 Diesel 对 mysql 进行简单的原始 SQL,如下例所示:

https://docs.diesel.rs/diesel/fn.sql_query.html

let users = sql_query("SELECT username FROM users").load(&connection);

但是这给了我一个错误信息:

error[E0282]: type annotations needed for `std::result::Result<Vec<T>, diesel::result::Error>`
  --> src/main.rs:53:57
   |
53 |     let users = sql_query("SELECT username FROM users").load(&connection);
   |         -----                                           ^^^^ cannot infer type for type parameter `U` declared on the associated function `load`
   |         |
   |         consider giving `users` the explicit type `std::result::Result<Vec<T>, diesel::result::Error>`, where the type parameter `U` is specified

附言。我需要使用原始 sql,因为我需要运行动态 sql。

【问题讨论】:

你有一个名为User的结构吗?如果是,您是否为该结构派生了#[derive(QueryableByName)]?如果是,您是否尝试通过添加属性#[table_name = "users"] 来指定与此结构相关的表?如果仍然是,您是否知道load(&amp;connection) 返回需要解包的Result&lt;Vec&lt;T&gt;, Err&gt;?如果仍然是,那么您是否尝试在局部变量上添加类型声明,如 let users: Vec&lt;User&gt; = .... 这能回答你的问题吗? Cannot infer type for `U` @TheCoolDrop 我没有 User 结构,因为我认为原始 sql 会让我在事先不知道结果的情况下运行动态 sql。那可能吗?如果事先不知道结果类型,我将运行的 sql 将更加复杂和动态。我该怎么做? 你怎么会不知道结果的类型呢?是不是你正在执行一个你事先不知道其结构的选择(或任何其他查询)?您将了解哪些有关表格的信息,哪些信息会丢失?你至少知道列数吗? @TheCoolDrop 我将有很多自定义函数,并且这些函数会传递各种属性。根据属性,函数将返回带有变量列的变量 json。 rust 有没有办法在不知道里面有什么的情况下接收自定义动态 json?类似于 Swift 的 Any 和 AnyObject 类型? 【参考方案1】:

据我所知,Diesel 无法在编译时不知道返回行的“形状”的情况下执行查询。这是它的优势之一(至少对于某些用例而言),因为使用得当,它将在编译时验证与数据库的交互。

但是,这使得动态生成的 SQL 难以使用。

如果您的查询总是生成相同数量和类型的列,那么您可以编写如下内容:

// Define a type to represent the rows returned by your query

#[derive(QueryableByName)]
struct StringColumn 
    #[sql_type = "Text"]
    username: String


// Then you can execute your query, telling Rust that you expect
// to get the rows back as the above type
let users:Vec<StringColumn> = diesel::sql_query("SELECT username FROM users").load(&conn)?;

如果您纯粹使用动态生成的 SQL,最好直接使用 mysql crate。

【讨论】:

虽然这确实有效(所以我接受了它),但它不符合我的需求。我的需求特别是我需要动态运行任何 SQL,而不必为每个查询创建结构,因为这需要我定义结构中的每一列 - 因此不会是动态的。我基本上想删除严格类型和编译时检查 SQL 列及其类型。我最终切换到 Postgres 数据库而不是 MYSQL 以及 Rust 方面的 r2d2_postgres。 Postgres 允许我使用 jsonb_agg(t)::text 将结果转换为 JSON 文本 & 我检索并发送为 &amp;str

以上是关于Rust Diesel 原始 SQL 给出错误“`std::result::Result<Vec<T>,diesel::result::Error>` 所需的类型注释”的主要内容,如果未能解决你的问题,请参考以下文章

Rust Diesel 无法编译并出现链接器错误

Rust Diesel 未构建错误使用未声明的板条箱或模块

如何在 Rust Diesel 中使用时间戳和间隔进行算术运算

如何使用Diesel格式化SQL结果的日期?锈

返回使用 Rocket 和 Diesel (Rust) 在 PostgreSQL 中创建的单个记录

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