我正在try 使用Rust中的sqlx::query!宏将数据插入到PostgreSQL数据库中.但是,我遇到了一个与uuid::Uuid类型不满足编码特性相关的编译错误.

Error Message:

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

Code Snippet:

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()
}

Cargo.toml Dependencies:

[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"

Attempts to Solve:

  • 我已经确保在sqlx中启用了UUID功能.
  • 我try 了不同版本的UUID以判断兼容性.
  • 在更改到Cargo.toml后,我运行了干净的Cargo 和Cargo 构建.

What could be causing this trait bound issue and how can I resolve it? Is there a version mismatch, or am I missing a necessary feature activation?

Update

我使用此代码更新了代码,但仍显示错误:

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的其他类型)的异步函数中使用 特征FromResidual<Result<Infallible, sqlx::types::uuid::Error>>不是针对HttpResponse实现

推荐答案

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()
}

Postgresql相关问答推荐

Qt,PostgreSQL -从NUERIC列检索max int64_t/uint64_t值

PostgreSQL中btree_gist索引涉及integer和tstzrange属性查询计划的问题

分区可以用于postgres中的同类查询吗?

无法在timscaleDb中创建Hypertable

如何在Postgres中对分区表使用Hibernate验证?

Gorm 创建表单数据文件上传错误

将数组的所有元素循环到jsonb中并修改值

查找行中的最小值

gorm 创建并返回值 many2many

如何检索 PostgreSQL 数据库的 comments ?

statement_date列是日期类型,但表达式是整数类型

'active' 标志与否?

从局域网访问 PostgreSQL 服务器

是否有为 SQL Server 生成完整数据库 DDL 的工具? Postgres 和 MySQL 呢?

如何使用字符串作为 PostgreSQL 咨询锁的键?

如何为查询执行设置语句超时

从time without time zone和时区名称中获取time with time zone

将属性添加到 Sequelize FindOne 返回的对象

SqlAlchemy:多列的不同计数

ruby on rails jsonb 列默认值