Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust cannot represent Postgres numeric type as BigDecimal type

I am writing simple rust web application using actix-web and sqlx.
I have struct Book with price field which should be mapped to postgres NUMERIC type. First I got error from sqlx that it was expecting bigdecimal type and suggested to enable this feature from cargo configuration, so I did. Then I imported BigDecimal from sqlx types and tried to use this type in my struct.

use sqlx::types::BigDecimal;

But I get this error:

12 |     pub price: BigDecimal,
   |     ^^^ the trait `configuration::_::_serde::Deserialize<'_>` is not implemented for `BigDecimal`

I tried to find solution to this problem, one possible solution was to use bigdecimal crate directly with serde enabled. So I tried to use bigdecimal type instead of sqlx one:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

use bigdecimal::BigDecimal;

But now I got different error:

the trait `sqlx::Type<Postgres>` is not implemented for `bigdecimal::BigDecimal`

Here is code I am using:

Book struct:

use chrono::{DateTime, Utc,};
use chrono::serde::ts_seconds;
//use sqlx::types::BigDecimal;
use bigdecimal::BigDecimal;


#[derive(serde::Deserialize)]
pub struct Book {
    pub author: String,
    pub title: String,
    pub pages: i32,
    pub price: BigDecimal,
    #[serde(with = "ts_seconds")]
    pub published_at: DateTime<Utc>
}

function that tries to insert Book data into database:

pub async fn insert_book(data: &Book, pool: &PgPool) -> Result<(), sqlx::Error> {
    sqlx::query!(
        r#"
            INSERT INTO books
            (id, author, title, pages, price, published_at)
            VALUES ($1, $2, $3, $4, $5, $6)
        "#,
        Uuid::new_v4(),
        data.author,
        data.title,
        data.pages,
        data.price,
        data.published_at
    )
        .execute(pool)
        .await
        .map_err(|e| {
            e
        })?;

    Ok(())
}

Simple POST endpoint:

#[post("/book")]
pub async fn add_new_book(data: web::Form<Book>, pool: web::Data<PgPool>) -> impl Responder {
    match insert_book(&data, &pool).await {
        Ok(_) => HttpResponse::Ok(),
        Err(e) => HttpResponse::InternalServerError()
    }
}

Cargo.toml

[dependencies]
secrecy = { version = "0.8", features = ["serde"] }
actix-web = "4.3.1"
serde = { version = "1", features = ["derive"]}
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
uuid = { version = "1.3.4", features = ["v4"] }
config = "0.11"
chrono = { version = "0.4.26", features = ["serde"] }
bigdecimal = { version = "0.2.0", features = ["serde"] }


[dependencies.sqlx]
version = "0.6.3"
default-features = false
features = [
    "runtime-actix-rustls",
    "macros",
    "postgres",
    "uuid",
    "chrono",
    "migrate",
    "bigdecimal"
]

Not sure how to fix this problem, any help will be appreciated.

>Solution :

You need to match the version of bigdecimal that sqlx uses (for sqlx 0.6.3, that would be bigdecimal 0.3.0).

It’s actually a dependency of sqlx_core

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading