微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rust Sqlx 句柄 INSERT ON CONFLICT

如何解决Rust Sqlx 句柄 INSERT ON CONFLICT

我有一个用户数据插入数据库查询。它工作正常,但 users 表在 username 上有一个唯一索引,因此当尝试使用已存在的用户名创建行时,它会引发错误

pub async fn create(user: UserRequest,pool: &PgPool) -> anyhow::Result<User> {
   let new_user = sqlx::query_as!(
       User,r#"
       INSERT INTO users (first_name,username)
       VALUES ($1,$2)
       RETURNING id,first_name,username
       "#,&user.first_name,&user.username,)
   .fetch_one(&pool.clone())
   .await?;
    
   Ok(User {
       id: new_user.id,first_name: new_user.first_name,username: new_user.username,})
}

&user一个函数参数,定义为:

pub struct UserRequest {
    pub first_name: String,pub username: String,}

使用此函数的端点使用 match 来检查它是否是 Ok(user) 或其他任何东西,并返回其响应:

pub async fn create_user(
    user: web::Json<UserRequest>,pool: Data<PgPool>,) -> impl Responder {
    let new_user = User::create(user.into_inner(),pool.get_ref()).await;
    match new_user {
        Ok(user) => HttpResponse::Ok().json(user),_ => HttpResponse::BadRequest().body(ERROR_MESSAGE),}
}

当由于行试图被复制而出现错误时,我该怎么做才能捕获这种情况?这种情况是我需要在发生这种情况时返回不同的 HTTP 状态。

解决方法

您可以使用 get_code 检查错误代码。

match new_user {
    Ok(user) => HttpResponse::Ok().json(user),Err(err) if err.get_code() == "23505" {
    // returns unique constraint violation response.
    },_ => HttpResponse::BadRequest().body(ERROR_MESSAGE),}

为了使这项工作如@MichaelAnderson 在评论中指出的那样,

您需要将 create 的返回类型更改为 Result<User,sqlx::postgres::PgDatabaseError>,或者您可以使用 anyhow::Error::downcast 或其相关函数返回 {{ 1}}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。