Diesel join 无法推断类型

Posted

技术标签:

【中文标题】Diesel join 无法推断类型【英文标题】:Diesel join cannot infer type 【发布时间】:2019-12-27 12:15:13 【问题描述】:

锈版本 1.18.3 柴油版 1.0.0 后格雷斯 11 在 Debian 10 上

我正在尝试使用 Diesel ORM 和 postgres 在 Rust 中加入两个表。该表是帖子和用户,我想将用户的用户名加入到帖子表中。

我在 CREATE TABLE 语句中的帖子中实现了一个外键,指向用户中的 id,因此柴油自动派生了可加入对象!和allow_tables_to_appear_in_same_query! schema.rs 中的宏。然而,当我尝试在我的代码中加入表格时,rust 无法推断出类型,我无法弄清楚如何注释类型。

这是我的 main.rs

extern crate cmsbackend;
extern crate diesel;

use self::cmsbackend::*;
use self::models::*;
use self::diesel::prelude::*;

fn main() 
    use cmsbackend::schema::*;

    let connection = establish_connection();

    let results = users::table.inner_join(posts::table)
        .select((users::name, posts::title))
        .load(&connection);

我收到此错误消息:

error[E0282]: type annotations needed for `std::result::Result<std::vec::Vec<U>, diesel::result::Error>`
  --> src/bin/main.rs:20:10
   |
18 |     let results = users::table.inner_join(posts::table)
   |         ------- consider giving `results` the explicit type `std::result::Result<std::vec::Vec<U>, diesel::result::Error>`, where the type parameter `U` is specified
19 |         .select((users::name, posts::title))
20 |         .load(&connection);
   |          ^^^^ cannot infer type for `U`

有关此错误的更多信息,请尝试rustc --explain E0282。 错误:无法编译cmsbackend

我是否可能需要在我的结构定义中派生其他内容:

use diesel::pg::data_types::*;

#[derive(Queryable)]
pub struct Post 
    pub id: i32,
    pub title: String,
    pub body: Option<String>,
    pub published: bool,
    pub user_id: i32,
    pub creation_date: PgTimestamp,
    pub last_edit: PgTimestamp,
    pub foto: Option<String>,


#[derive(Queryable)]
pub struct User 
    pub id: i32,
    pub name: String,
    pub pw: String,

如何编译?


编辑: 谢谢你的cmets。这是我的 schema.rs 的内容

table! 
    posts (id) 
        id -> Int4,
        title -> Varchar,
        body -> Nullable<Text>,
        published -> Bool,
        user_id -> Int4,
        creation_date -> Timestamp,
        last_edit -> Timestamp,
        foto -> Nullable<Varchar>,
    


table! 
    users (id) 
        id -> Int4,
        name -> Varchar,
        pw -> Varchar,
    


joinable!(posts -> users (user_id));

allow_tables_to_appear_in_same_query!(
    posts,
    users,
);

【问题讨论】:

返回类型是std::result::Result&lt;std::vec::Vec&lt;U&gt;, diesel::result::Error&gt;,Rust 编译器无法推断出U 是什么。这个inner_join 示例无需注释即可工作。但是因为我们不知道你的schema.rs 里面是什么,所以你是否使用infer_schema!,很难说。当自动调用joinable! & allow_tables_to_appear_in_same_query! 时检查the documentation。 您应该提供minimal reproducible example,而不仅仅是项目中的几行代码。如果我们不得不猜测,这很难提供帮助。 【参考方案1】:

我已经解决了这个问题。由于结构中的 Queryable 派生无法推断连接产生的数据类型,因此您必须像这样注释结构字段的数据类型:

let data: Vec<(String, String)> = users::table.inner_join(notes::table)
    .select((users::name, notes::title))
    .load(&connection)
    .expect("error");

在我尝试之前

let data: Vec<(User, Post)> = posts::table.inner_join(users::table)
.select((users::name, notes::title))
.load(&connection)
.expect("error");

编译器在加载时抛出了一个错误 Queryable 没有实现。

另见文档:https://github.com/diesel-rs/diesel/blob/master/guide_drafts/trait_derives.md

【讨论】:

以上是关于Diesel join 无法推断类型的主要内容,如果未能解决你的问题,请参考以下文章

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

无法推断类型参数“T”

无法推断类型

无法使用 SwiftUI 推断复杂的闭包返回类型

在 Kotlin 中无法“findViewById”。收到错误“类型推断失败”

通用扩展方法:无法从用法推断类型参数