尝试使用 Diesel 插入值时,“预期的结构字符串,发现结构模式::my_table::columns::my_column”

Posted

技术标签:

【中文标题】尝试使用 Diesel 插入值时,“预期的结构字符串,发现结构模式::my_table::columns::my_column”【英文标题】:"expected struct String, found struct schema::my_table::columns::my_column" when trying to insert value with Diesel 【发布时间】:2019-03-29 08:42:34 【问题描述】:

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

在插入函数中。

【问题讨论】:

请查看如何创建minimal reproducible example,然后查看edit 您的问题以包含它。例如,您还没有提供您的table! 宏调用(不完整),我们不需要知道任何关于 Rocket 的信息(不是最小的)。尝试在一个全新的 Cargo 项目中重现你的错误。有Rust-specific MCVE tips和Diesel-specific tips做小例子。 为不遵守 MCVE 道歉。我已经更新了问题。 为什么Project 相关?它在哪里使用?再次:最小 为什么提供SerializeDeserialize?他们是否需要重现问题? 最小. 什么版本的柴油机?您是否为 Diesel 使用任何 Cargo 功能? 【参考方案1】:

这是您的问题的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`

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

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

【讨论】:

以上是关于尝试使用 Diesel 插入值时,“预期的结构字符串,发现结构模式::my_table::columns::my_column”的主要内容,如果未能解决你的问题,请参考以下文章

Rust Diesel sql_query 带有返回的插入示例

Diesel 的 find 或 filter 的一般用法来执行删除

`bigdecimal::BigDecimal` 没有实现特征 `diesel::Expression`

<Struct> 没有实现特征 `diesel::Insertable<schema::trd::table>`

了解 Diesel 中的特征绑定错误

尝试在 SQL 中插入多个值时如何修复语句结尾?