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

使用diesel_ext生成模型时遇到字段类型未知问题求助

使用diesel_ext生成模型时遇到字段类型未知问题求助

嗨,我看你在用diesel_ext --model > src/models.rs生成模型的时候,碰到了role_name: /* TODO: unknown type Rolename */的问题,这大概率是因为diesel_ext没法自动识别数据库里的自定义Rolename类型(估计是自定义枚举类型对吧?),我之前也遇到过类似情况,给你几个实用的解决思路:

  • 先明确数据库里的Rolename类型:首先得确认这个类型在数据库里的定义——不管是PostgreSQL的ENUM、MySQL的枚举还是其他自定义类型,diesel_ext默认都没有内置的映射规则,需要我们手动在Rust代码里完成类型关联。

  • 手动实现自定义类型的Diesel映射:
    先在项目里定义对应的Rust枚举,再实现Diesel的FromSql和ToSql trait,把Rust类型和数据库类型绑定起来。以PostgreSQL为例:

    use diesel::sql_types::Text;
    use diesel::deserialize::{self, FromSql};
    use diesel::serialize::{self, ToSql};
    use std::io::Write;
    
    // 对应数据库里的Rolename枚举值,记得替换成你实际的枚举选项
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    pub enum Rolename {
        Admin,
        RegularUser,
        Guest,
    }
    
    // 实现从数据库类型转换到Rust类型
    impl FromSql<Text, diesel::pg::Pg> for Rolename {
        fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
            let role_str = String::from_sql(bytes)?;
            match role_str.as_str() {
                "admin" => Ok(Rolename::Admin),
                "regular_user" => Ok(Rolename::RegularUser),
                "guest" => Ok(Rolename::Guest),
                _ => Err(format!("未识别的角色类型: {}", role_str).into()),
            }
        }
    }
    
    // 实现从Rust类型转换到数据库类型
    impl ToSql<Text, diesel::pg::Pg> for Rolename {
        fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result {
            let role_str = match self {
                Rolename::Admin => "admin",
                Rolename::RegularUser => "regular_user",
                Rolename::Guest => "guest",
            };
            out.write_all(role_str.as_bytes())?;
            Ok(serialize::IsNull::No)
        }
    }
    

    如果用的是MySQL,只需要把diesel::pg::Pg换成diesel::mysql::Mysql,sql类型根据实际情况调整即可。

  • 修改生成的模型结构体:把生成的UserRole里的TODO注释替换成你定义的Rolename类型,比如:

    #[derive(Queryable, Debug)]
    pub struct UserRole {
        pub id: Uuid,
        pub user_id: Uuid,
        pub role_name: Rolename, // 替换掉原来的TODO注释
        pub created_at: Option<DateTime<Utc>>,
        // 注意:你提供的代码好像截断了,记得补全其他字段哦
    }
    
  • 用第三方库简化实现:要是不想手动写trait实现,可以试试diesel_enum这个crates,它能帮你自动生成必要的映射代码。先在Cargo.toml里添加依赖:

    [dependencies]
    diesel_enum = "0.4"
    

    然后用宏定义枚举:

    use diesel_enum::DbEnum;
    
    #[derive(Debug, Clone, Copy, PartialEq, Eq, DbEnum)]
    #[DbEnum(sql_type = "Text")] // 对应数据库里的类型
    pub enum Rolename {
        Admin,
        RegularUser,
        Guest,
    }
    

这样处理之后,role_name字段就能正常被Diesel识别和使用啦。

备注:内容来源于stack exchange,提问作者Maks.Burkov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:33:06