使用SurrealDB构建CRUD API时创建记录失败的问题求助
SurrealDB 创建记录时反序列化错误修复
问题场景
用SurrealDB构建CRUD API时,添加新记录触发反序列化异常。
请求JSON:
{"zipcode":"00-001","city":"Warsaw","country":"Poland","street":"Some street"}
错误响应:
Failed to convert `{ city: 'Warsaw', country: 'Poland', id: address:936jcs9jtx23qejgn5uc, street: 'Some street', zipcode: '00-001' }` to `T`: invalid type: map, expected a string
相关代码如下:
Address 模型
#[derive(Serialize, Deserialize, Debug)] pub struct Address { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option<String>, pub zipcode: String, pub city: String, pub country: String, pub street: String, } impl Address { pub fn new(zipcode: String, city:String, country:String, street: String) -> Address{ Address{ id: None, zipcode, city, country, street, } } }
Create 函数
pub type SurrealClient = Surreal<Client>; pub async fn create( client: Arc<SurrealClient>, zipcode: String, city: String, country: String, street: String, ) -> Result<Address, SurrealError> { let address: Address = Address::new(zipcode, city, country, street); match client.create("address").content(address).await{ Ok(address) => Ok(address), Err(e) => Err(e), } }
问题原因
错误根源在id字段的类型定义:SurrealDB返回的id是复合结构(格式表名:UUID),默认会被序列化为map类型,但代码中将id声明为Option<String>,serde无法完成类型转换,因此抛出异常。
解决方案
使用SurrealDB官方提供的Thing(或新版本的RecordId)类型替代String来定义id字段:
- 确保依赖中包含
surrealdb及相关serde特性 - 修改Address模型:
use surrealdb::sql::Thing; #[derive(Serialize, Deserialize, Debug)] pub struct Address { #[serde(skip_serializing_if = "Option::is_none")] pub id: Option<Thing>, pub zipcode: String, pub city: String, pub country: String, pub street: String, }
如果使用的是较新版本的SurrealDB,将Thing替换为RecordId即可,两者用法一致。
需要将id转为字符串时,直接调用id.to_string(),会得到address:936jcs9jtx23qejgn5uc格式的字符串,符合预期。
修改后无需改动create函数,客户端会自动完成正确的序列化与反序列化。
内容的提问来源于stack exchange,提问作者mmich
相关产品推荐
相关产品推荐

