`bigdecimal::BigDecimal` 未实现特性 `diesel::Expression`

10 postgresql rust rust-diesel

我正在尝试创建一个可以在柴油中用于插入的结构。具体来说,我正在使结构可插入。编译时出现此错误。

我有一个结构,我试图Insertable通过派生属性来制作。我有一个名为的字段Bounty,它应该代表钱,所以我使用它BigDecimal作为类型。编译后,我收到标题中的错误。我也试过使用,f64但这给出了同样的错误。

#[macro_use]
extern crate diesel;
extern crate bigdecimal;

mod schema {
    use bigdecimal::BigDecimal;
    table! {
        Threads (Id) {
            Id -> Int8,
            Views -> Int4,
            Points -> Int4,
            FlagPoints -> Int4,
            IsDisabled -> Bool,
            IsAnswered -> Bool,
            Bounty -> Numeric,
            Title -> Varchar,
            Body -> Text,
            UserId -> Int8,
            CreatedBy -> Varchar,
            CreatedOn -> Timestamptz,
            LastModifiedBy -> Varchar,
            LastModifiedOn -> Timestamptz,
        }
    }

    #[allow(non_snake_case)]
    #[derive(Debug, Insertable)]
    #[table_name = "Threads"]
    pub struct InsertableThread { 
        pub Bounty: BigDecimal,
        pub Title: String,
        pub Body: String,
        pub UserId: i64
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

我在它自己的文件中有我的结构,这是整个代码。该结构Thread编译没有问题。错误发生是InsertableThread因为它是使用BigDecimal. 这就是导致的错误。

#[macro_use]
extern crate diesel;
extern crate bigdecimal;

mod schema {
    use bigdecimal::BigDecimal;
    table! {
        Threads (Id) {
            Id -> Int8,
            Views -> Int4,
            Points -> Int4,
            FlagPoints -> Int4,
            IsDisabled -> Bool,
            IsAnswered -> Bool,
            Bounty -> Numeric,
            Title -> Varchar,
            Body -> Text,
            UserId -> Int8,
            CreatedBy -> Varchar,
            CreatedOn -> Timestamptz,
            LastModifiedBy -> Varchar,
            LastModifiedOn -> Timestamptz,
        }
    }

    #[allow(non_snake_case)]
    #[derive(Debug, Insertable)]
    #[table_name = "Threads"]
    pub struct InsertableThread { 
        pub Bounty: BigDecimal,
        pub Title: String,
        pub Body: String,
        pub UserId: i64
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Rust 1.34、柴油 1.4.2 和 Postgres 11。

我愿意更改数据库、Postgres 或 Rust 代码中的类型。数据库使用numeric和 在 Rust 代码中我已经尝试过f64BigDecimal。我也愿意自己直接实现这个特征,但我需要一些关于如何做到这一点的指导,因为我找不到样本。

She*_*ter 17

Diesel 使用Cargo 功能选择加入增强功能。

我还没有找到明确的文档页面,但它们列在Cargo.toml 中

[features]
default = ["with-deprecated", "32-column-tables"]
extras = ["chrono", "serde_json", "uuid", "deprecated-time", "network-address", "numeric", "r2d2"]
unstable = ["diesel_derives/nightly"]
large-tables = ["32-column-tables"]
huge-tables = ["64-column-tables"]
x32-column-tables = ["32-column-tables"]
32-column-tables = []
x64-column-tables = ["64-column-tables"]
64-column-tables = ["32-column-tables"]
x128-column-tables = ["128-column-tables"]
128-column-tables = ["64-column-tables"]
postgres = ["pq-sys", "bitflags", "diesel_derives/postgres"]
sqlite = ["libsqlite3-sys", "diesel_derives/sqlite"]
mysql = ["mysqlclient-sys", "url", "diesel_derives/mysql"]
with-deprecated = []
deprecated-time = ["time"]
network-address = ["ipnetwork", "libc"]
numeric = ["num-bigint", "bigdecimal", "num-traits", "num-integer"]
Run Code Online (Sandbox Code Playgroud)

您需要启用数字功能并确保使用与 Diesel 兼容的 bigdecimal 版本:

[dependencies]
diesel = { version = "1.4.2", features = ["numeric"] }
bigdecimal = "0.0.14"
Run Code Online (Sandbox Code Playgroud)

代码编译:

#[macro_use]
extern crate diesel;

use crate::schema::threads;
use bigdecimal::BigDecimal;

mod schema {
    table! {
        threads (id) {
            id -> Int4,
            bounty -> Numeric,
        }
    }
}

#[derive(Debug, Insertable)]
#[table_name = "threads"]
pub struct InsertableThread {
    pub bounty: BigDecimal,
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 谢谢牧马人。顺便说一句,我不得不将我的 BigDecimal 版本降级到 0.0.14。对于诸如此类的外部板条箱依赖项,柴油是否具有兼容性版本列表等? (2认同)

Bas*_*emm 9

除了添加"numeric"功能标志之外。Diesel 支持一系列 bigdecimal 版本:

\n
    \n
  • v1.4.8 支持bigdecimal >=0.0.10, <0.2.0
  • \n
  • v2.0.4 支持bigdecimal >=0.0.13, <0.4.0
  • \n
\n

但是,您在 crate 中使用的 bigdecimal 版本必须与 Diesel 使用的 bigdecimal 版本兼容。否则你可能会得到上面的错误。

\n

您可以使用 获取 Diesel 使用的版本cargo tree。命令和输出示例:

\n
> cargo tree -p diesel --depth=1\ndiesel v1.4.8\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bigdecimal v0.1.2 <-----------------\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bitflags v1.3.2\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 byteorder v1.4.3\n...\n
Run Code Online (Sandbox Code Playgroud)\n

根据上面的输出,您的内容Cargo.toml应该如下所示:

\n
[dependencies]\ndiesel = { version = "1.4.8", features = ["numeric", ...] }\nbigdecimal = "0.1.2" # <-----------------\n
Run Code Online (Sandbox Code Playgroud)\n