6

我正在尝试使用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()
}

并且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
}

项目表如下所示 -

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
);

和 schema.rs -

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

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

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

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

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

.values(&project)

而是在插入函数中。

4

1 回答 1

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() {}

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

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`

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

struct foo;
struct Thing { foo: String }

fn example(t: Thing) {
    let Thing { foo } = t;
}
error[E0308]: mismatched types
 --> src/lib.rs:5:17
  |
5 |     let Thing { foo } = t;
  |                 ^^^ expected struct `std::string::String`, found struct `foo`
  |
  = note: expected type `std::string::String`
             found type `foo`

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

struct foo;

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

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

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

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()
}
于 2018-10-24T20:54:08.980 回答