Rust 无法将 Postgres 数值类型表示为 BigDecimal 类型。

huangapple go评论85阅读模式
英文:

Rust cannot represent Postgres numeric type as BigDecimal type

问题

I am writing simple rust web application using actix-web and sqlx.
我正在编写一个简单的Rust Web应用程序,使用actix-websqlx

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:
但我收到了以下错误:

  1. 12 | pub price: BigDecimal,
  2. | ^^^ 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:
我尝试找到解决这个问题的方法,一个可能的解决方案是直接使用启用了serdebigdecimal crate。所以我尝试使用bigdecimal类型代替sqlx

  1. use bigdecimal::BigDecimal;

But now I got different error:
但现在我收到了不同的错误:

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

Here is code I am using:
这是我正在使用的代码:

Book struct:
Book结构体:

  1. use chrono::{DateTime, Utc,};
  2. use chrono::serde::ts_seconds;
  3. //use sqlx::types::BigDecimal;
  4. use bigdecimal::BigDecimal;
  5. #[derive(serde::Deserialize)]
  6. pub struct Book {
  7. pub author: String,
  8. pub title: String,
  9. pub pages: i32,
  10. pub price: BigDecimal,
  11. #[serde(with = "ts_seconds")]
  12. pub published_at: DateTime<Utc>
  13. }

function that tries to insert Book data into database:
尝试将Book数据插入数据库的函数:

  1. pub async fn insert_book(data: &Book, pool: &PgPool) -> Result<(), sqlx::Error> {
  2. sqlx::query!(
  3. r#"
  4. INSERT INTO books
  5. (id, author, title, pages, price, published_at)
  6. VALUES ($1, $2, $3, $4, $5, $6)
  7. "#,
  8. Uuid::new_v4(),
  9. data.author,
  10. data.title,
  11. data.pages,
  12. data.price,
  13. data.published_at
  14. )
  15. .execute(pool)
  16. .await
  17. .map_err(|e| e)?;
  18. Ok(())
  19. }

Simple POST endpoint:
简单的POST端点:

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

Cargo.toml
Cargo.toml文件:

  1. [dependencies]
  2. secrecy = { version = "0.8", features = ["serde"] }
  3. actix-web = "4.3.1"
  4. serde = { version = "1", features = ["derive"]}
  5. tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
  6. uuid = { version = "1.3.4", features = ["v4"] }
  7. config = "0.11"
  8. chrono = { version = "0.4.26", features = ["serde"] }
  9. bigdecimal = { version = "0.2.0", features = ["serde"] }
  10. [dependencies.sqlx]
  11. version = "0.6.3"
  12. default-features = false
  13. features = [
  14. "runtime-actix-rustls",
  15. "macros",
  16. "postgres",
  17. "uuid",
  18. "chrono",
  19. "migrate",
  20. "bigdecimal"
  21. ]

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.

  1. use sqlx::types::BigDecimal;

But I get this error:

  1. 12 | pub price: BigDecimal,
  2. | ^^^ the trait `configuration::_::_serde::Deserialize&lt;&#39;_&gt;` 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:

  1. use bigdecimal::BigDecimal;

But now I got different error:

  1. the trait `sqlx::Type&lt;Postgres&gt;` is not implemented for `bigdecimal::BigDecimal`

Here is code I am using:

Book struct:

  1. use chrono::{DateTime, Utc,};
  2. use chrono::serde::ts_seconds;
  3. //use sqlx::types::BigDecimal;
  4. use bigdecimal::BigDecimal;
  5. #[derive(serde::Deserialize)]
  6. pub struct Book {
  7. pub author: String,
  8. pub title: String,
  9. pub pages: i32,
  10. pub price: BigDecimal,
  11. #[serde(with = &quot;ts_seconds&quot;)]
  12. pub published_at: DateTime&lt;Utc&gt;
  13. }

function that tries to insert Book data into database:

  1. pub async fn insert_book(data: &amp;Book, pool: &amp;PgPool) -&gt; Result&lt;(), sqlx::Error&gt; {
  2. sqlx::query!(
  3. r#&quot;
  4. INSERT INTO books
  5. (id, author, title, pages, price, published_at)
  6. VALUES ($1, $2, $3, $4, $5, $6)
  7. &quot;#,
  8. Uuid::new_v4(),
  9. data.author,
  10. data.title,
  11. data.pages,
  12. data.price,
  13. data.published_at
  14. )
  15. .execute(pool)
  16. .await
  17. .map_err(|e| {
  18. e
  19. })?;
  20. Ok(())
  21. }

Simple POST endpoint:

  1. #[post(&quot;/book&quot;)]
  2. pub async fn add_new_book(data: web::Form&lt;Book&gt;, pool: web::Data&lt;PgPool&gt;) -&gt; impl Responder {
  3. match insert_book(&amp;data, &amp;pool).await {
  4. Ok(_) =&gt; HttpResponse::Ok(),
  5. Err(e) =&gt; HttpResponse::InternalServerError()
  6. }
  7. }

Cargo.toml

  1. [dependencies]
  2. secrecy = { version = &quot;0.8&quot;, features = [&quot;serde&quot;] }
  3. actix-web = &quot;4.3.1&quot;
  4. serde = { version = &quot;1&quot;, features = [&quot;derive&quot;]}
  5. tokio = { version = &quot;1&quot;, features = [&quot;macros&quot;, &quot;rt-multi-thread&quot;] }
  6. uuid = { version = &quot;1.3.4&quot;, features = [&quot;v4&quot;] }
  7. config = &quot;0.11&quot;
  8. chrono = { version = &quot;0.4.26&quot;, features = [&quot;serde&quot;] }
  9. bigdecimal = { version = &quot;0.2.0&quot;, features = [&quot;serde&quot;] }
  10. [dependencies.sqlx]
  11. version = &quot;0.6.3&quot;
  12. default-features = false
  13. features = [
  14. &quot;runtime-actix-rustls&quot;,
  15. &quot;macros&quot;,
  16. &quot;postgres&quot;,
  17. &quot;uuid&quot;,
  18. &quot;chrono&quot;,
  19. &quot;migrate&quot;,
  20. &quot;bigdecimal&quot;
  21. ]

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

huangapple
  • 本文由 发表于 2023年6月15日 05:04:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定