Rust Sqlx 处理 INSERT ON CONFLICT
Rust Sqlx handle INSERT ON CONFLICT
我有一个将用户数据插入数据库的查询。它工作正常,但是 users
table 在 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 (, )
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)
还是其他任何东西,并且 return 它的响应:
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),
}
}
当试图复制该行而出现错误时,我该怎么做才能捕捉到这种情况?情况是发生这种情况时我需要 return 不同的 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 在评论中指出的那样,
you'd need to change the return type of create to Result<User, sqlx::postgres::PgDatabaseError>
, or instead of changing the return type of create, you could use anyhow::Error::downcast
or its related functions to get back to a PgDatabaseError
我有一个将用户数据插入数据库的查询。它工作正常,但是 users
table 在 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 (, )
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)
还是其他任何东西,并且 return 它的响应:
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),
}
}
当试图复制该行而出现错误时,我该怎么做才能捕捉到这种情况?情况是发生这种情况时我需要 return 不同的 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 在评论中指出的那样,
you'd need to change the return type of create to
Result<User, sqlx::postgres::PgDatabaseError>
, or instead of changing the return type of create, you could useanyhow::Error::downcast
or its related functions to get back to aPgDatabaseError