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

如何为sqlx::query_as结果用自定义类型?遇FromRow trait约束不满足错误

解决Rust sqlx 0.7x中query_as反序列化自定义结构体的FromRow错误

你在使用sqlx 0.7x的query_as和fetch_all将SQLite查询结果转为Vec<Todo>时遇到了FromRow trait未实现的错误,核心原因是sqlx反序列化数据库查询结果依赖的是自身的FromRow trait,而非serde的Deserialize特性。

修复步骤

1. 为结构体派生sqlx的FromRow trait

修改结构体的derive属性,添加sqlx::FromRow,同时保留需要的serde特性:

use serde::{Deserialize, Serialize};
use sqlx::{FromRow, sqlite::SqlitePoolOptions};

#[derive(Serialize, Deserialize, FromRow)]
struct Todo {
    id: String,
    completed: bool,
}

2. 确保Cargo.toml启用正确的sqlx特性

sqlx的派生宏需要启用macros特性,同时要指定sqlite相关依赖特性,示例Cargo.toml配置:

[dependencies]
sqlx = { version = "0.7", features = ["sqlite", "macros", "runtime-tokio-native-tls"] }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }

3. 验证字段与数据库列名匹配

确保Todo结构体的字段名、类型与todos表的列完全对应:

  • 字段名需和列名一致(SQLite大小写不敏感,但严格匹配避免意外)
  • 类型要对应:比如数据库中id是文本类型,结构体用String;completed是布尔类型,结构体用bool

修正后的完整代码

use serde::{Deserialize, Serialize};
use sqlx::{FromRow, sqlite::SqlitePoolOptions};

#[derive(Serialize, Deserialize, FromRow)]
struct Todo {
    id: String,
    completed: bool,
}

#[tokio::main]
async fn main() {
    let pool = SqlitePoolOptions::new()
        .connect("sqlite:mydatabase.db")
        .await
        .expect("无法连接到数据库");

    let todos: Vec<Todo> = sqlx::query_as::<_, Todo>("SELECT * FROM todos")
        .fetch_all(&pool)
        .await
        .unwrap();
}

内容的提问来源于stack exchange,提问作者Alexander Staroselsky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:27:07