datadiffer

io.github.gauthierpiarrette由 GitHub 帳號 gauthierpiarrette 發布v0.1.0更新於 Oct 25, 2026

Read-only table diffs with segment attribution: which slice of your data changed.

已驗證STDIO僅桌面資料庫資料與分析

概覽

AI 產生的概覽

唯讀的資料表比對伺服器,讓助理比較兩張表,看出哪些列與欄位有變動,以及變動集中在哪個資料切片。

可以做什麼
列出已設定的連線,並比較兩張表或兩個資料來源的 schema 差異(本機檔案、DuckDB、Postgres、Snowflake)。先執行輕量的差異摘要作為預檢,再進行完整比對。產生完整差異報告:新增、刪除與修改的列數,各欄位的變更率,以及顯示哪個資料切片過度集中的分段歸因。連線以本機設定檔中的名稱引用,超出上限的請求會回傳結構化拒絕。
適用情境
適合助理或程式代理需要核對自己所做的資料或管線變更時使用,例如比較開發環境與正式環境,或將拉取請求副本與主分支對比,並說明差異集中在何處,而不只是判斷兩張表是否一致。
執行需求
以 stdio 在本機執行,通常透過 uvx 或加上 MCP 擴充套件的 pip 安裝。需要 datadiffer.toml 設定檔,其路徑由環境變數 DATADIFFER_CONFIG 指定,可用 init 指令產生範本。Postgres、Snowflake 的倉儲存取在該檔案中設定;本機 Parquet、CSV 與 DuckDB 不需憑證。比對在本機 DuckDB 中執行,每側上限為 5000 萬列與 10 GiB。
安裝前請注意
工具為唯讀,憑證不經過工具參數,而是保存在本機設定檔中,因此應保護該檔案。Postgres 讀取不做快照,結果可能反映正在變動的資料表。分段歸因僅為描述性,不能說明因果關係。大型比對受上限限制,可能需要縮小範圍。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 datadiffer,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

datadiffer

Diff two tables. See what changed, and which slice of your data it's concentrated in.

98.6% of modified rows have country = 'DE' (8.87x over-represented)

[PyPI] [CI] [License: MIT] [Python 3.10+]

datadiffer compares two tables (dev vs. prod, PR vs. main, source vs. destination) and tells you what changed and where it's concentrated: rows added / removed / modified, per-column change rates, and segment attribution.

Built for the era when agents write your pipelines and someone has to check their work. A maintained, MIT-licensed successor to the archived data-diff.

Try it in 60 seconds

No credentials, no config, no account. It generates its own data:

bash
uvx datadiffer demo

[datadiffer demo]

datadiffer-demo/orders_prod.parquet vs datadiffer-demo/orders_dev.parquetkey: order_id (inferred from *_id naming)rows: +800 added  -250 removed  ~432 modified  49318 unchanged┏━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓┃column ┃ changed rows ┃ % of matched┃┡━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩│amount │          432 │        0.87%│└───────┴──────────────┴─────────────┘-> 98.6% of modified rows have country = 'DE' (8.87x over-represented)   93.2% of added rows have plan = NULL (63.19x over-represented)sample changes:  [order_id=0]  amount: 5.0 -> 7.1  [order_id=1]  amount: 6.37 -> 6.38  [order_id=117]  amount: 32.4 -> 34.5  [order_id=234]  amount: 59.8 -> 61.9  [order_id=351]  amount: 87.2 -> 89.3DIFF FOUND

That last block is the point. A diff tells you 432 rows changed; datadiffer tells you they're almost all German orders, which is the difference between "something moved" and "the VAT change landed."

Install

bash
pip install datadiffer                      # local files: Parquet, CSV, DuckDBpip install 'datadiffer[snowflake]'         # + Snowflakepip install 'datadiffer[postgres]'          # + Postgrespip install 'datadiffer[mcp]'               # + MCP server for AI agents

Use it

bash
# local filesdatadiffer diff prod.parquet dev.parquet
# DuckDBdatadiffer diff prod.duckdb:orders dev.duckdb:orders
# Postgres (attached read-only)datadiffer diff orders orders_v2 --source "postgresql://user@host:5432/db"
# Snowflake, or anything in datadiffer.toml (run `datadiffer init` first)datadiffer diff wh::analytics.orders wh::analytics_dev.orders
# cross-source: warehouse vs. a local filedatadiffer diff wh::orders orders_snapshot.parquet
# machine-readable, for scripts and CIdatadiffer diff a.parquet b.parquet --format json

Exit codes follow the GNU diff convention: 0 no differences, 1 differences found, 2 operational error.

Useful flags: --key (inferred when omitted), --where, --columns / --exclude-columns, --sample-limit, --no-attribution, -q.

In your pull requests

datadiffer-action posts the report as a sticky PR comment:

datadiffer: ANALYTICS.ORDERS vs ANALYTICS_PR_482.ORDERS: differences found ❌

+800 added · −250 removed · ~432 modified · 49,318 unchanged (2.96% of base rows affected) Policy: max-changed-rows-pct exceeded: 2.96% > 0.5%

ColumnChanged rows% of matched
amount4320.87%

Where it's concentrated: 98.6% of modified rows have country = 'DE' (8.87× over-represented) 93.2% of added rows have plan = NULL (63.19× over-represented)

yaml
- uses: gauthierpiarrette/datadiffer-action@v1  with:    config: datadiffer.toml          # holds the warehouse connection    table-a: wh::ANALYTICS.ORDERS    schema-map: "ANALYTICS=ANALYTICS_PR_${PR_NUMBER}"    max-changed-rows-pct: "0.5"  env:    SNOWFLAKE_PRIVATE_KEY: ${{ secrets.SNOWFLAKE_PRIVATE_KEY }}

Running dbt? docs/dbt-ci.md turns dbt ls --select state:modified into one diff per changed model, each with its own comment.

For AI agents (MCP)

Let a coding agent verify its own data changes:

bash
datadiffer init          # scaffold datadiffer.toml, then add the server to your client
json
{ "mcpServers": { "datadiffer": { "command": "datadiffer", "args": ["mcp"] } } }

Any MCP client works. datadiffer init prints the server entry to paste, including a uvx form for clients that prefer no global install.

Four read-only tools: list_connections, schema_diff, diff_summary (cheap preflight), diff_tables (full report). Credentials never pass through the model. Tools take connection names from your local datadiffer.toml, never DSNs. Over-cap requests come back as structured refusals with a remedy, so the agent can self-correct instead of failing.

What makes it different

Most diff tools answer whether two tables match. datadiffer answers what changed and where: which columns moved, and which slice of the data the change is concentrated in.

ToolUse it instead when
DatafoldYou need billion-row cross-database reconciliation, a collaboration UI, lineage/impact analysis, and a support contract.
SQLMesh table_diffYou already run SQLMesh and diff within a single gateway (cross-database diffing is a Tobiko Cloud feature).
RecceYou want a dbt-native PR review UI and your whole workflow is dbt.
Google DVTYou're validating a migration across 17 warehouse types and want pass/fail validation with YAML configs.
datacompyYou're comparing two pandas/Spark/Polars DataFrames inside one process.

datadiffer is for the case in between: one command, no platform, works from your terminal, your CI, or your agent, and it explains itself.

Migrating from data-diff / reladiff

Same job, different flags:

data-diff / reladiffdatadiffer
data-diff DB1 table1 DB2 table2datadiffer diff <a> <b> (locators or --source/--target)
-k, --key-columns--key (repeatable, or comma-separated)
-c, --columns--columns
-w, --where--where (validated: single boolean expression, no subqueries)
--json--format json (stable schema v1)
-l, --limit--sample-limit

Differences worth knowing: keys are inferred from declared constraints or *_id conventions when you omit --key; unknown column names in filters are an error, never silently ignored; and exit code 1 means "diff found" (2 is reserved for operational errors), so CI can tell them apart.

Not yet ported: checksum-bisection hashdiff for very large cross-database diffs, which is reladiff's headline capability, plus MySQL, Oracle, ClickHouse, Trino and the rest of its connector list. If you need those today, use reladiff; the bisection port is the top item on our v0.2 roadmap and will credit its author.

Full command mapping and behavior differences: docs/migrating-from-data-diff.md.

Scope and limits (v0.1)

  • Warehouses: Snowflake, Postgres, DuckDB, Parquet, CSV. BigQuery is next (v0.1.1).
  • Every diff runs in local DuckDB. Postgres is attached read-only and scanned in place; Snowflake is pulled once over Arrow with only the needed columns. Both are capped at 50M rows and 10 GiB per side, so narrow the comparison with --where. Pushing the comparison into the warehouse, and lifting that cap with checksum bisection, are the next two pieces of work.
  • Postgres reads are unsnapshotted (the report says so in execution.snapshot); Snowflake pulls are a single consistent SELECT.
  • Segment attribution is single-column, categorical, and descriptive. It says "over-represented", never causal.

Project

MIT, no CLA, no telemetry. The report schema is frozen at v1 and contract-tested, so pipelines and agents that parse it keep working across releases. Dependencies are deliberately few: DuckDB, PyArrow, sqlglot, click, rich.

What's next

BigQuery, then checksum-bisection hashdiff so large cross-database diffs stop needing a row cap (ported with credit to reladiff), then more connectors. Tracked in issues. Comment on the one you need and it moves up.

Contributing

bash
git clone https://github.com/gauthierpiarrette/datadiffer && cd datadifferuv sync --group devuv run pytest -q            # warehouse tests skip unless credentials are setuv run ruff check .

Prior art gratefully acknowledged: data-diff and reladiff (Erez Shinan), whose checksum-bisection design v0.2 will port; Adtributor (Microsoft Research) for the attribution scoring; and DuckDB, which makes all of this fast enough to be boring.

License

MIT

來源:README.md,提交 05948c1

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.1.0最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分