使用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和ToSqltrait,把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
相关产品推荐
相关产品推荐

