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

Rust读取CSV导入SQLite时deserialize方法与返回类型报错如何解决

代码错误修复方案

错误原因说明

  1. 反序列化调用错误:rdr.records()返回的迭代器元素是Result<StringRecord, csv::Error>类型,直接对Result枚举调用deserialize方法找不到对应实现,需要先取出Result内的StringRecord再调用反序列化,或者直接使用csv crate提供的自动反序列化迭代器更简单。
  2. 返回值缺失错误:process_csv函数声明返回值为Result<(), Box<dyn Error>>,但函数逻辑走完后没有返回对应的Ok(()),导致返回值类型不匹配。
  3. 隐藏问题:建表SQL语句存在字段拼写错误,quanity应为quantity、quoted_quatity应为quoted_quantity,后续插入数据时会触发字段不存在错误。
  4. 导入冲突问题:同时导入了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:45:05