Skip to content

querybara data-compare

  • CLI
  • PostgreSQL
  • MySQL
  • MariaDB

querybara data-compare compares the rows of one table in two databases: the source holds the rows to copy, the target is the table to change. It reports the rows to insert, update and delete, and can write them as a sync script or apply them to the target and compare again.

Ranges of keys are checksummed on both servers, and only the ranges that do not match are streamed and merged, so matching data never leaves the servers. When the two sides are different engine families (PostgreSQL against MySQL or MariaDB), the rows are streamed and compared without checksums.

querybara data-compare --help
Usage: querybara data-compare [options] <source> <target>
compare the rows of a table in two databases and optionally sync the target
Arguments:
source the rows to copy from: profile or URI
target the table to change: profile or URI
Options:
--table <name> table to compare (schema.table on PostgreSQL)
--target-table <name> table name on the target (default: the same)
--key <columns> key columns (default: primary key or unique NOT
NULL key)
--columns <columns> compare only these columns
--ignore-columns <columns> leave these columns out
--actions <list> which differences to sync: insert,update,delete
--float-tolerance <n> treat floats within n as equal
--trim <mode> trim strings before comparing (choices: "none",
"trailing", "both")
--case-insensitive compare strings ignoring case
--show-rows <n> row differences to print (default: 10)
--batch-size <n> rows per INSERT or DELETE statement (default 500)
--disable-fk-checks skip foreign key checks while applying (MySQL
FOREIGN_KEY_CHECKS=0; PostgreSQL
session_replication_role, needs superuser)
--out <file> write the sync script
--json print counts and row differences as JSON
--apply apply the sync script to the target in one
transaction, then re-compare
-y, --yes confirm --apply when it deletes rows or the target
asks
--tls <mode> TLS mode for this run: disable, require, verify-ca
or verify-full
--ssh <user@host[:port]> reach URI targets through this SSH server; repeat
for jump hosts, in order
--ssh-key <path> SSH private key file (OpenSSH, PEM or PuTTY .ppk)
--ssh-password-env <VAR> take the SSH password from this variable (default
QUERYBARA_SSH_PASSWORD, else a prompt)
--ssh-agent log in with the keys of ssh-agent (SSH_AUTH_SOCK)
or Pageant
--proxy <url> reach URI targets (or their first SSH server)
through socks5://host:port or http://host:port
--ssh-accept-new trust and remember an SSH host key not seen before
(a changed key is always refused)
--known-hosts <path> SSH known hosts file (default: the desktop app's)
-h, --help show help for a command
Ranges of keys are checksummed on both servers; only mismatched ranges are streamed and
merged. Exit codes: 0 no differences (for the selected actions), 1 differences found or
remaining after --apply, 2 error.
Examples:
querybara data-compare prod staging --table public.plans
querybara data-compare prod staging --table plans --actions insert,update --out sync.sql
querybara data-compare seed test --table countries --apply --yes

The --tls and SSH options are described in Global options.

Compare a table and print the first row differences:

Terminal window
querybara data-compare shop-prod shop-staging --table shop.products

Write a script that only inserts and updates:

Terminal window
querybara data-compare shop-prod shop-staging --table shop.products --actions insert,update --out sync.sql

Sync a reference table into a test database:

Terminal window
querybara data-compare shop-seed shop-test --table shop.countries --apply --yes

Compare a table under another name, on a subset of its columns:

Terminal window
querybara data-compare shop-prod shop-archive --table shop.orders --target-table shop.orders_2026 --columns id,status,total

Rows are matched on the key columns: by default the primary key, or a unique NOT NULL key. Name them with --key when the table has neither. --columns and --ignore-columns choose what is compared; --float-tolerance, --trim and --case-insensitive relax how values are compared.

--show-rows sets how many row differences are printed (10 by default); the counts, the script and --apply always cover every row.

--apply runs the sync script on the target in one transaction, then compares again.

  • The CLI asks before applying when the script deletes rows, or the target is a production or confirm-writes profile. Without a terminal, pass --yes.
  • A read-only target refuses --apply.
  • --disable-fk-checks turns foreign key checks off while applying: FOREIGN_KEY_CHECKS=0 on MySQL and MariaDB, session_replication_role on PostgreSQL, which needs a superuser.
Code Meaning
0 No differences for the selected actions, or --apply left none
1 Differences found, or some remain after --apply
2 Error, including a failed or unconfirmed apply
130 Interrupted

Documents Querybara 0.1.1 · built frombc9f5aa