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:
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.
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