postgresql sqlx::query!Macro with uuid::Uuid无法在Rust中编译

qij5mzcb  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(167)

我尝试在Rust中使用sqlx::query!宏将数据插入到PostgreSQL数据库中。但是,我遇到了与uuid::Uuid类型不满足Encode trait相关的编译错误。

错误信息:

不满足特性界限uuid::Uuid: Encode<'_, Postgres>

验证码:

use actix_web::{web, HttpResponse};
use sqlx::PgPool;
use uuid::Uuid;
use chrono::Utc;

pub async fn subscribe(form: web::Form<FormData>, connection: web::Data<PgPool>) -> HttpResponse {
    sqlx::query!(
        r#"
        INSERT INTO subscriptions (id, email, name, subscribed_at)
        VALUES ($1, $2, $3, $4)
        "#,
        Uuid::new_v4(),
        form.email,
        form.name,
        Utc::now()
    )
    .execute(connection.get_ref())
    .await;
    HttpResponse::Ok().finish()
}

字符串

货物清单:

[dependencies]
actix-web = "4.4.0"
sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio-rustls", "macros", "postgres", "uuid", "chrono"] }
uuid = { version = "0.8.1", features = ["v4", "serde"] }
chrono = "0.4.15"

尝试解决:

  • 我已经确保在sqlx中启用了uuid特性。
  • 我尝试了不同版本的uuid来检查兼容性。
  • 我在更改Cargo.tom l后运行了cargo clean和cargo build。
    是什么原因导致了这个trait绑定问题,我该如何解决?是版本不匹配,还是我错过了必要的功能激活?
    更新

我用这个代码更新代码,但仍然显示错误:

use actix_web::{web, HttpResponse};
use chrono::Utc;
use sqlx::types::Uuid;
use sqlx::PgPool;

#[derive(serde::Deserialize)]
pub struct FormData {
    email: String,
    name: String,
}

pub async fn subscribe(form: web::Form<FormData>, connection: web::Data<PgPool>) -> HttpResponse {
    let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;
    
    sqlx::query!(
        r#"
    INSERT INTO subscriptions (id, email, name, subscribed_at)
    VALUES ($1, $2, $3, $4)
    "#,
        my_uuid,
        form.email,
        form.name,
        Utc::now()
    )
    // We use `get_ref` to get an immutable reference to the `PgConnection`
    // wrapped by `web::Data`.
    .execute(connection.get_ref())
    .await;
    HttpResponse::Ok().finish()
}


它显示了这个错误:

let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;


?运算符只能用在返回ResultOption(或实现FromResidual的其他类型)的aprc函数中trait FromResidual<Result<Infallible, sqlx::types::uuid::Error>>不为HttpResponse实现

kpbwa7wx

kpbwa7wx1#

sqlx不知道如何序列化Uuid,但它知道如何序列化String,因此您可以使用Uuid上的to_string方法将Uuid转换为String

pub async fn subscribe(form: web::Form<FormData>, connection: web::Data<PgPool>) -> HttpResponse {
    sqlx::query!(
        r#"
    INSERT INTO subscriptions (id, email, name, subscribed_at)
    VALUES ($1, $2, $3, $4)
    "#,
        // Here we use the `to_string` method on `Uuid`
        Uuid::new_v4().to_string(),
        form.email,
        form.name,
        Utc::now()
    )
    .execute(connection.get_ref())
    .await;

    HttpResponse::Ok().finish()
}

字符串
在代码的更新版本中,您正在将String解析为Uuid,这可能会失败,这就是为什么Uuid::parse方法返回Result,您可以解包它(如果您确定它是有效的Uuid)或像这样处理错误:

pub async fn subscribe(form: web::Form<FormData>, connection: web::Data<PgPool>) -> HttpResponse {
    // unwrap it
    let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8").unwrap();

    // or, handle the error
    let my_uuid = match Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8") {
        Ok(uuid) => uuid,
        Err(err) => {
            return HttpResponse::BadRequest().body("Invalid uuid");
        }
    };
    
    sqlx::query!(
        r#"
    INSERT INTO subscriptions (id, email, name, subscribed_at)
    VALUES ($1, $2, $3, $4)
    "#,
        // We have to convert `Uuid` to `String`
        my_uuid.to_string(),
        form.email,
        form.name,
        Utc::now()
    )
    .execute(connection.get_ref())
    .await;
    HttpResponse::Ok().finish()
}

相关问题