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

Rust+SurrealDB调用create方法报错:期望字符串却得到map

Rust + SurrealDB create方法类型不匹配错误解决

问题概述

使用Rust官方SDK调用SurrealDB的create方法时,持续触发类型不匹配错误:"invalid type: map expected a string",无论是否传入Todo结构体内容都会报错。

错误信息

初始写法报错:

Err(Api(FromValue { value: Array(Array([Object(Object({"completed": Bool(false), "content": Strand(Strand("Teste content")), "createdAt": Strand(Strand("2023-12-06T11:51:13.110266200Z")), "id": Thing(Thing { tb: "todo", id: String("47f46af4-27e8-4c22-9711-f49b9a866e82") }), "title": Strand(Strand("Teste")), "updatedAt": Strand(Strand("2023-12-06T11:51:13.110266200Z"))}))])), error: "invalid type: map, expected a string" }))

简化写法后报错:

Err(Api(FromValue { value: Array(Array([Object(Object({"id": Thing(Thing { tb: "todo", id: String("08kipc79181usjbuxlnu") })}))])), error: "invalid type: map, expected a string" }))

相关代码片段

仓库中create方法初始写法

// todo_repository.rs
pub async fn create(&self, content: Todo) -> Result<Vec<Todo>, Error> {
    let record = DB.create(&self.table).content(content).await?;
    Ok(record)
}

排查用的简化写法

// todo_repository.rs
pub async fn create(&self, content: Todo) -> Result<Vec<Todo>, Error> {
    let record = DB.create("todo").await?;
    Ok(record)
}

数据库连接配置

// surreal_context.rs
pub static DB: Lazy<Surreal<Client>> = Lazy::new(Surreal::init);

pub async fn connect_db() -> Result<()> {
    let _ = DB.connect::<Ws>("localhost:8000").await?;
    let _ = DB.signin(Root {
        username: "root",
        password: "root",
    })
    .await;
    let _ = DB.use_ns("todo").use_db("todo").await?;
    Ok(())
}

// main.rs
#[tokio::main]
async fn main() {
    let _ = connect_db().await;
...
}

最小复现代码

#![allow(unused)]
use chrono::{DateTime, Utc};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use surrealdb::{Surreal, Result, engine::remote::ws::{Client, Ws}, opt::auth::Root};

#[allow(non_snake_case)]
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Todo {
    pub id: Option<String>,
    pub title: String,
    pub content: String,
    pub completed: Option<bool>,
    pub createdAt: Option<DateTime<Utc>>,
    pub updatedAt: Option<DateTime<Utc>>,
}

pub static DB: Lazy<Surreal<Client>> = Lazy::new(Surreal::init);

pub async fn connect() -> Result<()> {
    let _ = DB.connect::<Ws>("localhost:8000").await?;
    let _ = DB.signin(Root {
        username: "root",
        password: "root",
    })
    .await;
    let _ = DB.use_ns("todo").use_db("todo").await?;
    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    let _ = connect().await;

    let record: Vec<Todo> = DB.create("todo").await?;
    
    Ok(())
}

依赖配置

[dependencies]
axum = "0.7.1"
chrono = { version = "0.4.31", features = ["serde"] }
once_cell = "1.18.0"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
surrealdb = "1.0.0"
tokio = { version = "1.34.0", features = ["full"] }
tower-http = { version = "0.5.0", features = ["cors"] }
uuid = { version = "1.6.1", features = ["v4", "serde"] }

解决方案

错误根源是**Todo结构体的id字段类型不匹配**:SurrealDB返回的id是Thing类型(包含表名和ID字符串的复合结构),但结构体中定义为Option<String>,导致反序列化时类型转换失败。

修复步骤:

  1. 导入SurrealDB的Thing类型:use surrealdb::sql::Thing;
  2. 修改Todo结构体的id字段类型为Option<Thing>

修改后的Todo结构体:

#[allow(non_snake_case)]
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Todo {
    pub id: Option<Thing>,
    pub title: String,
    pub content: String,
    pub completed: Option<bool>,
    pub createdAt: Option<DateTime<Utc>>,
    pub updatedAt: Option<DateTime<Utc>>,
}
  1. 如果需要将Thing转为字符串使用,可以调用Thing::to_string()方法,例如:
if let Some(id) = &todo.id {
    let id_str = id.to_string();
    // 使用id_str
}

另外,确保在调用create方法时传入正确的Todo实例(带title和content必填字段):

// 示例调用
let new_todo = Todo {
    id: None,
    title: "Teste".to_string(),
    content: "Teste content".to_string(),
    completed: Some(false),
    createdAt: None, // SurrealDB可自动生成,也可手动设置
    updatedAt: None,
};

let records: Vec<Todo> = DB.create("todo").content(new_todo).await?;

内容的提问来源于stack exchange,提问作者Vitor Lacerda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:38:13