SQLx+SQLite中id字段被错误推断为Option<i64>的问题
问题:SQLx中UPDATE返回的id字段被推断为Option而非i64
我在使用Actix Web、SQLx crate和SQLite数据库开发待办事项应用后端时,执行UPDATE查询后发现,返回的Record类型中id字段被推断为Option<i64>而非i64类型。该字段在数据库迁移中被声明为PRIMARY KEY NOT NULL,按理应是i64类型。重新运行sqlx migrate run后问题依然存在,目前只能通过if let Some(id)来处理这个Option类型,但这不符合数据库定义的约束。
数据库迁移代码
CREATE TABLE IF NOT EXISTS todos ( id INTEGER PRIMARY KEY NOT NULL, description TEXT NOT NULL, done BOOLEAN NOT NULL DEFAULT 0 );
Cargo.toml配置
[package] name = "server" version = "0.1.0" edition = "2021" [[bin]] name = "todos" path = "src/main.rs" [dependencies] actix-web = "4.3.1" anyhow = "1.0.71" dotenvy_macro = "0.15.7" serde = { version = "1.0.169", features = ["derive"] } sqlx = { version = "0.7", features = [ "sqlite", "runtime-tokio" ] }
接口处理代码
use actix_web::{ put, web::{self, Json}, HttpResponse, Responder, }; use serde::{Deserialize, Serialize}; use crate::AppData; #[derive(Serialize)] pub struct ErrorResponse { error: String, } #[derive(Deserialize)] pub struct PutTodoRequest { pub id: i64, pub description: String, pub done: bool, } #[derive(Serialize)] pub struct TodoResponse { pub id: i64, pub description: String, pub done: bool, } #[put("/todo/")] async fn put_todo(body: Json<PutTodoRequest>, app_data: web::Data<AppData>) -> impl Responder { let body = body.into_inner(); let result = sqlx::query!( "UPDATE todos SET description = $1, done = $2 WHERE id = $3 RETURNING *;", body.description, body.done, body.id ) .fetch_one(&app_data.db_pool) .await; if let Err(e) = result { return HttpResponse::InternalServerError().json(ErrorResponse { error: e.to_string(), }); } if let Ok(data) = result { if let Some(id) = data.id { return HttpResponse::Ok().json(TodoResponse { id, description: data.description, done: data.done, }); } return HttpResponse::InternalServerError().json(ErrorResponse { error: "id was null, somehow...".to_owned(), }); } HttpResponse::InternalServerError().json(ErrorResponse { error: "I did not expect this.".to_owned(), }) }
内容的提问来源于stack exchange,提问作者Gabriel Pureliani
相关产品推荐
相关产品推荐

