You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:45:58