Rust读取CSV导入SQLite时deserialize方法与返回类型报错如何解决
代码错误修复方案
错误原因说明
- 反序列化调用错误:
rdr.records()返回的迭代器元素是Result<StringRecord, csv::Error>类型,直接对Result枚举调用deserialize方法找不到对应实现,需要先取出Result内的StringRecord再调用反序列化,或者直接使用csv crate提供的自动反序列化迭代器更简单。 - 返回值缺失错误:
process_csv函数声明返回值为Result<(), Box<dyn Error>>,但函数逻辑走完后没有返回对应的Ok(()),导致返回值类型不匹配。 - 隐藏问题:建表SQL语句存在字段拼写错误,
quanity应为quantity、quoted_quatity应为quoted_quantity,后续插入数据时会触发字段不存在错误。 - 导入冲突问题:同时导入了
rusqlite::Result和标准库的Result会产生类型冲突,需要调整导入规则。
修复后完整代码
use walkdir::WalkDir; use rusqlite::{params, Connection}; use std::error::Error; use std::path::Path; use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct Trade { id: usize, price: f64, quantity: f64, quoted_quantity: f64, time: i64, is_buyer_maker: bool, is_best_match: bool, } fn process_csv(file: &Path, db: &Connection) -> Result<(), Box<dyn Error>> { let mut rdr = csv::Reader::from_path(file)?; // 直接使用deserialize迭代器自动反序列化到Trade类型 for result in rdr.deserialize::<Trade>() { match result { Ok(s) => { db.execute("INSERT INTO trades (id, price, quantity, quoted_quantity, time, is_buyer_maker, is_best_match) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", params![s.id, s.price, s.quantity, s.quoted_quantity, s.time, s.is_buyer_maker, s.is_best_match])?; }, Err(e) => println!("Failed to deserialize: {}", e), } } // 补充返回值 Ok(()) } fn main () -> Result<(), Box<dyn Error>> { let conn = Connection::open("bot.db")?; // 修复建表字段拼写错误,添加IF NOT EXISTS避免重复运行报错 conn.execute( "CREATE TABLE IF NOT EXISTS trades ( id INTEGER PRIMARY KEY, price REAL NOT NULL, quantity REAL NOT NULL, quoted_quantity REAL NOT NULL, time INTEGER NOT NULL, is_buyer_maker INTEGER NOT NULL, is_best_match INTEGER NOT NULL )", [], )?; // 过滤仅处理csv后缀文件,避免处理目录/其他格式文件报错 for entry in WalkDir::new("E:/binance-public-data/python/data/spot/monthly/trades/") .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.path().extension().and_then(|ext| ext.to_str()) == Some("csv")) { println!("Processing: {}", entry.path().display()); if let Err(e) = process_csv(entry.path(), &conn) { println!("Processing failed: {}", e); } } Ok(()) }
额外优化说明
- 建表语句添加
IF NOT EXISTS,重复运行程序不会触发表已存在的错误 - 遍历文件新增csv后缀过滤,避免处理非目标文件产生不必要的报错
- 移除未使用的导入项,减少编译警告
内容的提问来源于stack exchange,提问作者Vobliss
相关产品推荐
相关产品推荐

