英文:
Rust cannot represent Postgres numeric type as BigDecimal type
问题
I am writing simple rust web application using actix-web
and sqlx
.
我正在编写一个简单的Rust Web应用程序,使用actix-web
和sqlx
。
I have struct Book
with price
field which should be mapped to postgres NUMERIC
type.
我有一个名为Book
的结构体,其中包含应该映射到PostgreSQL的NUMERIC
类型的price
字段。
First I got error from sqlx
that it was expecting bigdecimal
type and suggested to enable this feature from cargo configuration, so I did.
首先,我收到了来自sqlx
的错误,它期望bigdecimal
类型,并建议从Cargo配置中启用此功能,所以我这样做了。
Then I imported BigDecimal
from sqlx types and tried to use this type in my struct.
然后,我从sqlx类型中导入了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:
我尝试找到解决这个问题的方法,一个可能的解决方案是直接使用启用了serde
的bigdecimal
crate。所以我尝试使用bigdecimal
类型代替sqlx
:
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:
Book结构体:
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:
尝试将Book
数据插入数据库的函数:
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端点:
#[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
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.
不确定如何解决这个问题,将不胜感激任何帮助。
英文:
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.
答案1
得分: 4
你需要匹配 sqlx 使用的 bigdecimal
版本(对于 sqlx 0.6.3,应使用 bigdecimal 0.3.0)。
这实际上是 sqlx_core
的依赖项。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论