"ожидаемая структура String, найдена структура схемы :: my_table :: columns :: my_column" при попытке вставить значение с помощью Diesel - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь выполнить вставку нескольких столбцов, используя Дизель с 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()
}

И Project и NewProject

#[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,
}

При компиляции я получаю сообщение об ошибке -

title |^^^^^ ожидаемая структура std::string::String, найденная структура schema::projects::columns::title

и

.execute (conn) |^^^^^^^ ожидаемая структура diesel::query_source::Never, найденная структура diesel::query_source::Once

Я не получаю ошибку компиляции при выполнении

.values(&project)

в функции вставкивместо этого.

1 Ответ

0 голосов
/ 24 октября 2018

Вот 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()
}
...