关于 Dataparity
Dataparity 提供 CLI、MCP 服务和库,可比较同一数据库或不同数据库中的表。它为 Agent 返回变更详情、归因和风险判断;跨库比较时,行数据留在各自数据库内。
主要功能
- 01跨数据库表比较
- 02可移植的规范行哈希
- 03列级变更详情
- 04变更归因与风险判断
- 05只读 MCP 工具
适用场景
- 01检查生产与暂存表的差异
- 02将数据库表与 Parquet 或 CSV 数据比较
- 03在 CI 中执行数据差异检查
MCP 相关
它提供四种只读工具,用于列出数据源、查看表信息和比较表内容。工具使用数据源名称而非连接字符串,且不会写入数据库。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
4收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
Dataparity
为 AI Agent 提供跨数据库数据差异比较与协调功能,并支持可移植的行哈希。
比较两个表格——无论它们位于同一个数据库还是两个不同的数据库——并获取变更内容、发生变更的列,以及变更集中在哪部分数据中。 可作为命令行工具、MCP 服务和库运行。采用 MIT 许可证。
功能
提供两个表格和一个键,即可了解变更内容:
HIGH 3 difference(s) found across 5 row(s) (60.00% of the left side).
left pg :: public.orders_prod (5 rows)
right mysql :: analytics.orders_staging (5 rows)
strategy checksum keys id
added 1 removed 1 modified 1 unchanged 3
where the changes are concentrated:
country = DE 4 change(s) 80.0% of changes 6.7x over-represented
sample changes:
removed key=2
modified key=3 amount
added key=6
signals:
- 1 row(s) exist only on the left
- 1 row(s) exist only on the right
- 1 row(s) differ in at least one column
与自己编写的 SELECT EXCEPT 相比,它有三个不同之处:
-
可跨两个不同的数据库使用。 Postgres ↔ MySQL、Postgres ↔ DuckDB、 Parquet ↔ Postgres。两侧都在各自的引擎中计算相同的规范行哈希,因此只有哈希会通过网络传输——绝不传输行数据。
-
它会指出变更发生在哪里,而不只是告知存在变更。 如果差异比较只报告 “432 行不同”,几乎毫无用处。而如果报告“98.6% 的已修改行都是德国订单”,就能告诉你增值税规则已生效,其他内容则未受影响。
-
专为 Agent 构建。 MCP 服务提供四个只读工具、稳定的 JSON 结果契约,以及可供编码 Agent 执行操作的风险判定(
none/low/medium/high/critical)。
哈希为何可移植
要跨引擎比较行,就必须对值的含义达成一致。Postgres 和 MySQL 中的 0.1 都是最接近十分之一的双精度浮点数,而 0.1 + 0.2 并不等于 0.3。
在 Postgres 中,布尔值是 true,在 MySQL 中则是 1。一个引擎中的时间戳精度为微秒,另一个引擎中的则为秒。NULL 不等于空字符串。
Dataparity 通过两条规则解决这个问题,并在每个引擎中以相同方式应用:
- 为每个值添加类型标记。 NULL 表示为
N;其他每个值都表示为V,后接其规范化文本。NULL 和''永远不会混淆,真实值也永远不会被误认为 NULL。 - 将每个值按长度前缀编码后再拼接成行哈希。包含字段分隔符的文本值无法移动列边界并伪造匹配结果。
浮点数会先在精确十进制算术中缩放到固定小数位数,再进行表示,因此 0.1 + 0.2 和 0.3 会得到一致结果。时间戳会规范化为 UTC 并截断到秒。布尔值在所有地方都表示为 true / false。
最终得到的 MD5 行哈希在不同引擎之间逐字节一致。这并非 README 中的一纸声明,而是由 test/integration/canonical.test.ts 断言:该测试会将相同的特殊值写入 Postgres、MySQL 和 DuckDB,并要求哈希匹配:
docker run -d --name pgdiff -e POSTGRES_PASSWORD=test -e POSTGRES_DB=difftest -p 55432:5432 postgres:16-alpine
docker run -d --name mydiff -e MYSQL_ROOT_PASSWORD=test -e MYSQL_DATABASE=difftest -p 53306:3306 mysql:8
npm run test:integration
这些测试需要数据库。如果某个数据库无法访问,测试会报告为已跳过,而不是通过,因此绿色运行绝不意味着“什么都没测”——如果有任何测试被跳过,CI 就会使任务失败。
安装
npm install -g dataparity
也可以不安装,直接运行:
npx dataparity --help
需要 Node.js 22.16 或更高版本。
CLI
在 ~/.dataparity/config.json 中配置一次数据源(或将 DATAPARITY_CONFIG 指向其他路径):
{
"sources": [
{ "name": "prod", "type": "postgres", "connectionString": "postgres://..." },
{ "name": "staging", "type": "postgres", "connectionString": "postgres://..." },
{ "name": "mysql", "type": "mysql", "host": "127.0.0.1", "port": 3306,
"user": "readonly", "password": "...", "database": "analytics" },
{ "name": "local", "type": "sqlite", "path": "data/app.db" },
{ "name": "files", "type": "duckdb", "files": ["data/orders.parquet"] }
]
}
然后进行差异比较:
# Two tables in the same database
dataparity diff \
--left prod --right staging \
--left-table public.orders_prod --right-table public.orders_staging \
--key id
# Two tables in two different databases
dataparity diff \
--left prod --right mysql \
--left-table public.orders_prod --right-table orders_staging \
--key id --json
# Explore first
dataparity tables --source prod
dataparity describe --source prod --table public.orders_prod
退出码遵循 GNU diff 约定:0 表示相同,1 表示发现差异,2 表示错误。
因此可以直接用于 CI 检查。
| 选项 | 含义 |
|---|---|
--left、--right | 配置文件中的数据源名称 |
--left-table、--right-table | 要比较的表 |
--key | 用于匹配行的逗号分隔键列 |
--columns | 要比较的列(默认为所有共有列) |
--where | 应用于两侧的 WHERE 表达式 |
--max-changes | 要报告的最大行变更数(默认为 100) |
--max-attributions | 要报告的最大归因片段数(默认为 5) |
--sample | 仅比较样本;结果会标记为抽样结果 |
--sample-limit | 每侧的最大抽样行数(默认为 100000) |
--bucket-count | 跨数据库差异比较的显式分桶数 |
--json | 机器可读输出 |
凭据可以通过环境变量提供,而不必写入磁盘:
export DATAPARITY_PROD_CONNECTION_STRING='postgres://...'
export DATAPARITY_MYSQL_PASSWORD='...'
MCP
claude mcp add --scope user dataparity -- npx -y dataparity mcp
或在 .cursor/mcp.json 中配置:
{
"mcpServers": {
"dataparity": { "command": "npx", "args": ["-y", "dataparity", "mcp"] }
}
}
四个只读工具:
| 工具 | 功能 |
|---|---|
dataparity_list_sources | 已配置的数据源及其引擎类型 |
dataparity_list_tables | 数据源中的表及其列 |
dataparity_describe_table | 单个表的列、类型和可空性 |
dataparity_diff | 比较两张表并报告变更 |
工具接收数据源 名称,而非连接字符串——凭据不会经过模型。所有工具均为只读;dataparity 不会向数据库写入任何内容。
库
import { diffTables, PostgresSource, MysqlSource } from 'dataparity';
const prod = await PostgresSource.connect({ connectionString: process.env.PROD_URL! });
const staging = await MysqlSource.connect({
host: '127.0.0.1', port: 3306, user: 'ro', password: '...', database: 'analytics',
});
const report = await diffTables(prod, 'public.orders', staging, 'orders_staging', {
keyColumns: ['id'],
});
if (report.risk.level === 'critical') {
console.error(report.risk.signals.join('\n'));
process.exit(1);
}
工作原理
同一数据库 → 单次数据库内联接。 三路分类(新增、移除、修改)通过一个反联接和一个外联接完成,完全在数据库内部执行。行数据不会离开数据库,结果准确无误。
不同数据库 → 规范化哈希,按分桶比较。 两侧分别在各自的引擎中计算每个桶的计数和两个独立校验和。只有聚合结果不一致的桶才会展开到行级别,因此,即使十亿行的表只有少数行存在差异,也只会传输少量哈希,而不是十亿行数据。
归因。 对于每个候选列,会将该列在变更行中的分布与其在整个表中的分布进行比较。如果某个值在变更行中的出现频率远高于预期,就表明受影响的数据切片可能与该值有关。评分仅作描述(“占比过高”),并不表示因果关系。
风险。 判定会综合考虑变更规模与架构差异。如果新增或移除行的同时还移除了列或更改了列类型,则风险为 critical;如果变更行占比很小且架构没有变化,则风险为 low。
支持的引擎
| 引擎 | 同库 | 跨库 | 备注 |
|---|---|---|---|
| PostgreSQL | 是 | 是 | |
| MySQL | 是 | 是 | |
| SQLite | 是 | 是 | 通过 node:sqlite,默认只读 |
| DuckDB | 是 | 是 | 可直接读取 Parquet、CSV 和 JSON |
| Parquet / CSV / JSON | — | 是 | 通过 DuckDB |
布尔值和 0/1 整数会被视为相同的逻辑类型,因此,Postgres 中的布尔列可以正确地与 SQLite 不得不使用的整数列进行比较。
状态
早期阶段。核心功能稳固,并已针对实时 Postgres、MySQL 和 DuckDB 完成测试,但功能范围较小,边界条件也较为严格。
目前可用的功能
- 同一数据库之间的差异比较,提供精确到列级别的详情
- Postgres、MySQL、SQLite 和 DuckDB 之间的跨数据库差异比较
- 架构比较、变更归因、风险评估
- CLI、MCP 服务和类型化库 API
- 设计上只读;凭据不会传给模型
- 跨数据库差异比较可定位哪些列发生了变化:通过在每个引擎内部计算逐列哈希进行比较,因此即使经过哈希比较,列级详情也能保留下来,且不会有任何值通过网络传输
已知限制
- 跨数据库差异比较会报告哪些列发生了变化,但不会报告变更前后的值:只有哈希会通过网络传输,因此值本身不会离开任一引擎。同一数据库内的差异比较也会包含值。
- JSON 列会按文本进行比较,因此键顺序不同也会被判定为变更。请改为进行结构化比较。
- 浮点数和十进制数会比较到小数点后六位。超过此精度时,两个引擎对末尾位的结果可能不一致。
where子句是原始 SQL 片段。它会传给你的引擎,而不是模型,但请将其视为可信输入。- 没有监控、没有血缘图、没有 dbt 集成,也没有 UI。
贡献
docs/design.md 是功能范围及其关键决策的权威依据。更改行为前请先阅读——其中记录的是决策理由,而不只是结果。
工作流程如下:
npm ci
npm test # unit tests
npm run test:integration # needs live Postgres + MySQL; skips if absent
npm run test:audit # every engine x every option x every error path
npm run lint
npm run typecheck
npm run build
集成测试套件需要 Postgres 16 在 :55432 上运行,MySQL 8 在 :53306 上运行:
docker run -d --name pgdiff -e POSTGRES_PASSWORD=test -e POSTGRES_DB=difftest -p 55432:5432 postgres:16-alpine
docker run -d --name mydiff -e MYSQL_ROOT_PASSWORD=test -e MYSQL_DATABASE=difftest -p 53306:3306 mysql:8
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。