#csv #difference #compare #diff #primary-key #database-table

csv-diff

以惊人的速度比较两个CSV文件 🚀

7个版本

0.1.0 2023年10月30日
0.1.0-beta.42023年2月26日
0.1.0-beta.12023年1月7日
0.1.0-beta.02022年12月4日
0.1.0-alpha2021年12月30日

#313 in 编码

Download history 319/week @ 2024-03-14 299/week @ 2024-03-21 322/week @ 2024-03-28 318/week @ 2024-04-04 264/week @ 2024-04-11 280/week @ 2024-04-18 324/week @ 2024-04-25 296/week @ 2024-05-02 325/week @ 2024-05-09 326/week @ 2024-05-16 337/week @ 2024-05-23 311/week @ 2024-05-30 309/week @ 2024-06-06 353/week @ 2024-06-13 364/week @ 2024-06-20 263/week @ 2024-06-27

每月1,335次下载
qsv中使用

MIT/Apache

240KB
5.5K SLoC

csv-diff

以惊人的速度找到两个CSV文件之间的差异!🚀


Pipeline Status Crates.io version Downloads docs.rs docs


文档

https://docs.rs/csv-diff

⚠️警告⚠️

该crate仍处于初级阶段。在初期可能会有破坏性变更(以及龙🐉)。

✨ 突出亮点

  • 🚀世界上最快的CSV比较库
    • 在600ms内比较包含1,000,000行x 9列的CSV文件
  • 🧵🧶 无线程池限制

示例

use std::io::Cursor;
use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv};
use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord};
use std::collections::HashSet;
use std::iter::FromIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // some csv data with a header, where the first column is a unique id
    let csv_data_left = "id,name,kind\n\
                        1,lemon,fruit\n\
                        2,strawberry,fruit";
    let csv_data_right = "id,name,kind\n\
                        1,lemon,fruit\n\
                        2,strawberry,nut";

    let csv_byte_diff = CsvByteDiffLocal::new()?;

    let mut diff_byte_records = csv_byte_diff.diff(
        Csv::with_reader_seek(csv_data_left.as_bytes()),
        Csv::with_reader_seek(csv_data_right.as_bytes()),
    )?;

    diff_byte_records.sort_by_line();

    let diff_byte_rows = diff_byte_records.as_slice();

    assert_eq!(
        diff_byte_rows,
        &[DiffByteRecord::Modify {
            delete: ByteRecordLineInfo::new(
                csv::ByteRecord::from(vec!["2", "strawberry", "fruit"]),
                3
            ),
            add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["2", "strawberry", "nut"]), 3),
            field_indices: vec![2]
        }]
    );
    Ok(())
}

入门指南

在您的Cargo.toml文件中,在 [dependencies] 下添加以下行

csv-diff = "0.1.0"

这将使用rayon线程池,但您可以选择不使用它,例如不使用线程池使用线程,通过启用 crossbeam-threads 特性(并禁用默认特性)

csv-diff = { version = "0.1.0", default-features = false, features = ["crossbeam-threads"] }

用例

此crate应用于具有某种 主键 以唯一标识记录的CSV数据。它 不是 一个通用的逐行比较crate。您可以想象将来自 测试生产 系统的数据库表以CSV格式导出,并相互比较以找到差异。

注意事项

由于此crate仍处于初级阶段,还有一些注意事项,我们 可能会 在不久的将来解决

  • 如果两个CSV文件都有标题,则它们 不得 按不同的顺序排列(另请参阅 #6#3
  • 存在差异的CSV记录/行以原始字节的形式提供;您可以使用由StringRecord::from_byte_record提供的csv crate尝试将它们转换为UTF-8编码的记录。
  • 文档需要改进

基准测试

您可以使用以下命令运行基准测试

cargo bench

安全性

此crate使用#![forbid(unsafe_code)]100% Safe Rust中实现,这通过使用unsafe_code来确保。

最低支持的Rust版本(MSRV)

此crate的最低支持Rust版本是1.65。MSRV的增加将通过小版本号(根据SemVer)的变更来指示。

致谢

此crate受到Aswin Karthik编写的Go语言CLI工具csvdiff的启发。绝对值得一试。它是一个伟大的工具。

此外,如果没有出色的Rust社区和这些出色的crate 🦀,这个crate将不会存在。




许可证

根据您的选择,此crate受Apache License, Version 2.0MIT许可证许可。
除非您明确声明,否则您提交给此crate的任何有意提交的供包括在内的贡献,根据Apache-2.0许可证定义,应按上述方式双重许可,不附加任何额外条款或条件。

依赖项

~2.7–4MB
~60K SLoC