postgresql 使用u128的 Package 类型扩展Diesel时出错

fgw7neuy  于 11个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(180)

我在下面的代码中遇到了困难,我试图为u128创建一个自定义类型U128,Diesel默认情况下没有实现。我的目标是将u128原语存储在Postgresql数据库中,无论是文本格式还是数字格式(最好是数字格式)。

use std::io::Write;
use diesel::{AsExpression, deserialize, FromSqlRow, serialize};
use diesel::deserialize::{FromSql};
use diesel::pg::{Pg};
use diesel::serialize::{IsNull, Output, ToSql};
use diesel::sql_types::{Text};

#[derive(AsExpression, FromSqlRow, Debug, Clone, Copy)]
#[diesel(sql_type = Text)]
pub struct U128(pub u128);

impl ToSql<Text, Pg> for U128 {
    fn to_sql<'b>(&self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        write!(out, "{}", self.0.to_string())?;
        Ok(IsNull::No)
    }
}

impl FromSql<Text, Pg> for U128 {
    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
        let s = String::from_utf8_lossy(bytes.as_bytes());
        Ok(U128(s.parse()?))
    }
}

字符串
这是我创建的柴油结构。

#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::schema::balance)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Balance {
    pub id: i32,
    pub account_name: String,
    pub balance: u128,
}


这是我尝试在diesel结构中使用u128时遇到的编译错误。

error[E0277]: the trait bound `u128: diesel::Queryable<diesel::sql_types::Text, Pg>` is not satisfied
   --> src\models.rs:117:27
    |
117 |     pub balance: u128,
    |                  ^^^^ the trait `diesel::Queryable<diesel::sql_types::Text, Pg>` is not implemented for `u128`
    |
    = help: the following other types implement trait `diesel::Queryable<ST, DB>`:
              i8
              i16
              i32
              i64
              u8
              u16
              u32
              u64
            and 2 others
    = note: required for `u128` to implement `FromSqlRow<diesel::sql_types::Text, Pg>`
    = help: see issue #48214

wfauudbj

wfauudbj1#

diesel不会神奇地应用任何可能工作的 Package 器,这是不可能的,相反,你必须告诉它,它应该使用(de)serialize_as属性的中间类型:

#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::schema::balance)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Balance {
    pub id: i32,
    pub account_name: String,
    #[diesel(serialize_as = U128, deserialize_as = U128)]
    pub balance: u128,
}

字符串
要做到这一点,diesel还需要一种方法来转换你的 Package 器从/到目标类型,你可以用From trait来提供:

impl From<u128> for U128 {
    fn from(v: u128) -> U128 {
        U128(v)
    }
}

impl From<U128> for u128 {
    fn from (v: U128) -> u128 {
        v.0
    }
}


注意事项:diesel使用TryInto进行转换,但由于这个是可靠的,并且有一系列的一揽子实现可以让我们免费实现,所以我实现了From

相关问题