compare_tables
Compares a table before and after a pipeline change to detect lost or duplicated rows, changed keys and values, null spikes, shifted totals, and schema changes, returning pass, review, or block.
Instructions
Compare one table before and after a pipeline change and say whether the change harmed the data.
It looks for the damage that a green job and passing tests miss: rows lost or duplicated (a join that
fans out, a dedupe that drops too much), keys that disappeared, values that changed in columns the
change was not meant to touch, a jump in nulls, a shifted total (a unit or currency change), new or
vanished categories, and schema or type changes.
Use this after you edit a SQL query, dbt model, Spark job or load, or after an agent applies a fix,
and before you report the work as done, merge it or publish the table. Use check_against_source
instead when there is no earlier snapshot but you have the raw input the table was built from, and
run_config when the project already has a pipeverify.yml listing its tables.
Behavior: read-only and repeatable. Both snapshots are read (files are opened read-only; Snowflake,
dbt and SQL sources run one SELECT each, with credentials already configured on this machine, never
passed as arguments) and loaded into a temporary in-memory DuckDB where the checks run. Nothing is
written anywhere. Each snapshot is loaded whole, so for a large warehouse table pass a SELECT or a
'where' filter covering the slice you changed. Usually takes seconds. Fails with a readable error
if a file, table, dbt model, key column or login is wrong.
Returns verdict ("pass", "review" or "block"), headline (one sentence you can show the user), and
tables: one entry with stats (row counts and more) and findings, each with check, severity, message,
column and metrics. On "review" or "block", tell the user every finding and do not apply the change.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"before": "<before>",
"after": "<after>"
},
"name": "compare_tables"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Column or columns that together identify one row, for example ["order_id"] or ["store_id", "sale_date"]. Without a key only table-level checks run (row counts, schema, null rates, totals), so give one whenever the table has it. | |
| name | No | Name to show for the table in the report, for example gold.daily_sales. Defaults to 'table'. | |
| after | Yes | The same table after the change (for example the pull request's build). Same forms as 'before'. | |
| before | Yes | The table as it was before the change (for example production, or yesterday's snapshot). A file path (.csv, .parquet, .json, .xlsx; CSV and JSON may be .gz or .zst), 'duckdb:<file.db>:<table or SELECT>', 'snowflake:<DB.SCHEMA.TABLE or SELECT>', 'dbt:<model>', or an object such as {"dbt": "fct_orders", "project_dir": "analytics", "target": "prod", "manifest": "prod-manifest.json"}, {"snowflake": "DB.SCHEMA.T", "connection": "name", "where": "..."} or {"url": "<SQLAlchemy URL>", "table": "schema.table"}. Relative paths are relative to the server's working folder. | |
| ignore | No | Columns to skip because they always differ, such as load timestamps or run ids. | |
| thresholds | No | Optional overrides for when a difference becomes review or block, in percent of rows, for example {"row_change_block_pct": 20, "sum_shift_review_pct": 1}. Omit to use the defaults. | |
| expect_change | No | Columns this change is meant to modify. Differences in them are reported as expected instead of flagged. Omit when the change should not alter any existing value. | |
| expect_row_change | No | Set true when the change is meant to add or remove rows, so a row-count change alone is not flagged. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tables | Yes | ||
| seconds | Yes | ||
| verdict | Yes | ||
| version | Yes | ||
| headline | Yes |