You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Diesel 2无法反序列化Uuid的编译错误排查求助

Diesel查询PostgreSQL时的FromStaticSqlRow trait绑定错误

问题场景

使用Actix Web结合Diesel操作PostgreSQL数据库时,编写用户查询接口出现编译错误,相关代码及错误信息如下:

接口代码

pub async fn get(
        user_uuid: web::Path<uuid::Uuid>,
        data: web::Data<AppState>,
    ) -> Result<impl Responder, actix_web::Error> {
        use crate::schema::users::dsl::*;
        let mut conn = get_conn(&data.pool).await?;
        use uuid::Uuid;
        let user_id = user_uuid.into_inner();

        let result: Result<User, diesel::result::Error> = users.find(user_id).first(&mut conn);
        
    }

依赖配置

diesel = {version = "2.1.3", features = ["postgres", "chrono", "r2d2", "uuid", "serde_json"]}
uuid = { version = "1.4.1", features = ["serde", "v4"] }

User模型

#[allow(non_snake_case)]
#[derive(Debug, Insertable, Queryable, AsChangeset, Serialize, Deserialize, Clone)]
pub struct User {
    pub id: uuid::Uuid,
    pub name: String,
    pub email: String,
    pub password: String,
    pub is_admin: bool,
    #[serde(rename = "createdAt")]
    pub created_at: Option<NaiveDateTime>,
    #[serde(rename = "updatedAt")]
    pub updated_at: Option<NaiveDateTime>,
}

schema.rs定义

diesel::table! {
    users (id) {
        id -> Uuid,
        #[max_length = 100]
        name -> Varchar,
        #[max_length = 255]
        email -> Varchar,
        is_admin -> Bool,
        #[max_length = 100]
        password -> Varchar,
        created_at -> Nullable<Timestamptz>,
        updated_at -> Nullable<Timestamptz>,
    }
}

编译错误信息

server % cargo check              
    Checking server v0.1.0 
error[E0277]: the trait bound `(uuid::Uuid, std::string::String, std::string::String, std::string::String, bool, std::option::Option<NaiveDateTime>, std::option::Option<NaiveDateTime>): FromStaticSqlRow<(diesel::sql_types::Uuid, Text, Text, diesel::sql_types::Bool, Text, diesel::sql_types::Nullable<diesel::sql_types::Timestamptz>, diesel::sql_types::Nullable<diesel::sql_types::Timestamptz>), Pg>` is not satisfied
    --> src/routes/user.rs:44:85
     |
44   |         let result: Result<User, diesel::result::Error> = users.find(user_id).first(&mut conn);
     |                                                                               ----- ^^^^^^^^^ the trait `FromStaticSqlRow<(diesel::sql_types::Uuid, Text, Text, diesel::sql_types::Bool, Text, diesel::sql_types::Nullable<diesel::sql_types::Timestamptz>, diesel::sql_types::Nullable<diesel::sql_types::Timestamptz>), Pg>` is not implemented for `(uuid::Uuid, std::string::String, std::string::String, std::string::String, bool, std::option::Option<NaiveDateTime>, std::option::Option<NaiveDateTime>)`
     |                                                                               |
     |                                                                               required by a bound introduced by this call
     |
     = help: the following other types implement trait `FromStaticSqlRow<ST, DB>`:
               <(T0,) as FromStaticSqlRow<(ST0,), __DB>>
               <(T1, T0) as FromStaticSqlRow<(ST1, ST0), __DB>>
               <(T1, T2, T0) as FromStaticSqlRow<(ST1, ST2, ST0), __DB>>
               <(T1, T2, T3, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST0), __DB>>
               <(T1, T2, T3, T4, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST0), __DB>>
               <(T1, T2, T3, T4, T5, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST0), __DB>>
               <(T1, T2, T3, T4, T5, T6, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST0), __DB>>
               <(T1, T2, T3, T4, T5, T6, T7, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST0), __DB>>

错误原因

核心问题是User结构体的字段顺序与schema.rs中定义的数据库表字段顺序不匹配。

Diesel的Queryable trait要求结构体字段顺序必须和数据库表(schema.rs)的字段顺序完全一致,否则在反序列化查询结果时,类型映射会出现错位,导致编译器抛出FromStaticSqlRow trait未实现的错误。

对比两者的字段顺序:

  • schema.rs中users表字段顺序:id → name → email → is_admin → password → created_at → updated_at
  • User结构体字段顺序:id → name → email → password → is_admin → created_at → updated_at

可以看到password和is_admin的顺序在结构体和schema中颠倒,导致Diesel无法正确映射字段类型。

解决方法

调整User结构体的字段顺序,使其与schema.rs中定义的表字段顺序完全一致:

修改后的User模型代码:

#[allow(non_snake_case)]
#[derive(Debug, Insertable, Queryable, AsChangeset, Serialize, Deserialize, Clone)]
pub struct User {
    pub id: uuid::Uuid,
    pub name: String,
    pub email: String,
    pub is_admin: bool,  // 将is_admin移至password之前,与schema顺序对齐
    pub password: String,
    #[serde(rename = "createdAt")]
    pub created_at: Option<NaiveDateTime>,
    #[serde(rename = "updatedAt")]
    pub updated_at: Option<NaiveDateTime>,
}

修改完成后重新执行cargo check或cargo build,错误即可消除。

额外提示:

  • 后续修改schema或结构体时,务必保持两者的字段顺序一致
  • 若不想依赖字段顺序,可使用Diesel的#[diesel(column_name = "...")]属性显式指定字段映射,但对于简单场景,保持顺序一致更直观

内容的提问来源于stack exchange,提问作者Nikita Prokaiev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:42:32