尝试使用 Diesel 插入值时出现“预期的结构字符串,找到结构架构::my_table::columns::my_column”

Ram*_*lya 6 postgresql rust rust-diesel

我正在尝试使用Diesel和 PostgreSQL执行插入多个列。

这是添加新的插入功能Project-

pub fn insert(project: NewProject, program_id: i32, conn: &PgConnection) -> bool {
    use schema::projects::dsl::*;
    use schema::projects::dsl::{title as t};
    use schema::projects::dsl::{program_id as prog_id};

    let NewProject {
        title
    } = project;

    diesel::insert_into(projects)
        .values((t.eq(title), prog_id.eq(program_id)))
        .execute(conn)
        .is_ok()
}
Run Code Online (Sandbox Code Playgroud)

ProjectNewProject

#[derive(Queryable, Serialize, Debug, Clone)]
pub struct Project {
    pub id: i32,
    pub title: String,
    pub program_id: i32,
    pub is_archived: bool
}

#[derive(Serialize, Deserialize, Insertable)]
#[table_name = "projects"]
pub struct NewProject {
    pub title: String
}
Run Code Online (Sandbox Code Playgroud)

项目表看起来像这样 -

CREATE TABLE projects (
    id SERIAL PRIMARY KEY,
    title VARCHAR NOT NULL,
    program_id INTEGER NOT NULL REFERENCES programs (id),
    is_archived BOOLEAN NOT NULL DEFAULT FALSE
);
Run Code Online (Sandbox Code Playgroud)

和 schema.rs -

table! {
projects (id) {
    id -> Int4,
    title -> Varchar,
    program_id -> Int4,
    is_archived -> Bool,
}
Run Code Online (Sandbox Code Playgroud)

编译时,我收到一条错误消息 -

标题 | ^^^^^ 预期结构std::string::String,找到结构schema::projects::columns::title

.execute(conn) | ^^^^^^^ 预期结构 diesel::query_source::Never,找到结构 diesel::query_source::Once

当我这样做时,我没有收到编译错误

.values(&project)
Run Code Online (Sandbox Code Playgroud)

在插入函数中。

She*_*ter 9

这是您的问题的MCVE

#[macro_use]
extern crate diesel;

use diesel::pg::PgConnection;
use diesel::prelude::*;

mod schema {
    table! {
        projects (id) {
            id -> Int4,
            title -> Varchar,
            program_id -> Int4,
            is_archived -> Bool,
        }
    }

    #[derive(Debug, Insertable)]
    #[table_name = "projects"]
    pub struct NewProject {
        pub title: String,
    }
}

use schema::NewProject;

fn insert(project: NewProject, program_id: i32, conn: &PgConnection) -> bool {
    use schema::projects::dsl::*;
    use schema::projects::dsl::{title as t};
    use schema::projects::dsl::{program_id as prog_id};

    let NewProject {
        title
    } = project;

    diesel::insert_into(projects)
        .values((t.eq(title), prog_id.eq(program_id)))
        .execute(conn)
        .is_ok()
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

您导入了一个title与解构冲突的类型,如错误消息所述:

#[macro_use]
extern crate diesel;

use diesel::pg::PgConnection;
use diesel::prelude::*;

mod schema {
    table! {
        projects (id) {
            id -> Int4,
            title -> Varchar,
            program_id -> Int4,
            is_archived -> Bool,
        }
    }

    #[derive(Debug, Insertable)]
    #[table_name = "projects"]
    pub struct NewProject {
        pub title: String,
    }
}

use schema::NewProject;

fn insert(project: NewProject, program_id: i32, conn: &PgConnection) -> bool {
    use schema::projects::dsl::*;
    use schema::projects::dsl::{title as t};
    use schema::projects::dsl::{program_id as prog_id};

    let NewProject {
        title
    } = project;

    diesel::insert_into(projects)
        .values((t.eq(title), prog_id.eq(program_id)))
        .execute(conn)
        .is_ok()
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

这可以简化为一个非常小的情况:

struct foo;
struct Thing { foo: String }

fn example(t: Thing) {
    let Thing { foo } = t;
}
Run Code Online (Sandbox Code Playgroud)
error[E0308]: mismatched types
  --> src/main.rs:34:22
   |
34 |     let NewProject { title } = project;
   |                      ^^^^^ expected struct `std::string::String`, found struct `schema::projects::columns::title`
   |
   = note: expected type `std::string::String`
              found type `schema::projects::columns::title`
Run Code Online (Sandbox Code Playgroud)

请注意,此 struct 定义时没有大括号,这使其成为类似单元的 struct。这些很方便,但它们具有微妙的细微差别,即它们创建了类型

struct foo;

fn example() {
    let foo: foo = foo;
    //             ^-- the only value of the type `foo`
    //       ^-------- the type `foo`
    //  ^------------- newly-defined unrelated identifier
}
Run Code Online (Sandbox Code Playgroud)

解构时,模式首选作为类型,而不是标识符。

不要导入该类型,您不会有冲突:

fn insert(project: NewProject, program_id: i32, conn: &PgConnection) -> bool {
    use schema::projects::dsl;

    let NewProject { title } = project;

    diesel::insert_into(dsl::projects)
        .values((dsl::title.eq(title), dsl::program_id.eq(program_id)))
        .execute(conn)
        .is_ok()
}
Run Code Online (Sandbox Code Playgroud)