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(&connection)
返回需要解包的Result<Vec<T>, Err>
?如果仍然是,那么您是否尝试在局部变量上添加类型声明,如 let users: Vec<User> = ....
这能回答你的问题吗? 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 文本 & 我检索并发送为 &str
以上是关于Rust Diesel 原始 SQL 给出错误“`std::result::Result<Vec<T>,diesel::result::Error>` 所需的类型注释”的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Rust Diesel 中使用时间戳和间隔进行算术运算