The zero-dependency regression testing tool for modern data warehouses. DuckDB-powered data diffing for Snowflake.
Project description
quack-diff
The zero-dependency regression testing tool for modern data warehouses.
DuckDB-powered data diffing for Snowflake.
Features
- DuckDB-First Architecture: Uses DuckDB as a universal adapter for database connectivity
- Dialect-Safe Hashing: Handles NULL values and type mismatches correctly across databases
- Time-Travel Support: Compare data against historical snapshots (Snowflake, Delta Lake)
- CI/CD Ready: Exit codes for pipeline integration, environment variable configuration
- Hacker-Friendly: Rich terminal output with beautiful diff tables
Installation
uv add quack-diff
Quick Start
Basic Diff
# Compare two tables
quack-diff diff --source db1.users --target db2.users --key id
# Compare with threshold (allow up to 1% difference)
quack-diff diff --source prod.orders --target dev.orders --key order_id --threshold 0.01
Time-Travel Diff (Snowflake)
# Compare current data with 5 minutes ago
quack-diff diff \
--source snowflake.orders \
--target snowflake.orders \
--source-at "5 minutes ago" \
--key order_id
Schema Comparison
quack-diff schema --source db1.users --target db2.users
Configuration
quack-diff supports configuration via environment variables:
# Snowflake
export QUACK_DIFF_SNOWFLAKE_ACCOUNT="your-account"
export QUACK_DIFF_SNOWFLAKE_USER="your-user"
export QUACK_DIFF_SNOWFLAKE_PASSWORD="your-password"
Or via a quack-diff.yaml configuration file:
snowflake:
account: your-account
user: your-user
database: your-database
defaults:
threshold: 0.0
How It Works
quack-diff leverages DuckDB's extension system to connect to external databases:
- Attach: Mount remote databases using DuckDB extensions (snowflake)
- Hash: Generate row-level hashes using dialect-safe SQL (handles NULLs, type coercion)
- Compare: Identify mismatches by comparing hash values
- Report: Display results in beautiful terminal tables
Development
# Clone the repository
git clone https://github.com/matteorenoldi/quack-diff.git
cd quack-diff
# Install with dev dependencies
uv sync
# Install pre-commit hooks
uv run prek install
# Run tests
uv run pytest
# Lint
uv run ruff check .
License
MIT License - see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quack_diff-0.0.5.tar.gz.
File metadata
- Download URL: quack_diff-0.0.5.tar.gz
- Upload date:
- Size: 162.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84848ad1d60e489e3be582e7726f97bf98c2256c8cf47cefa09a228f4e210800
|
|
| MD5 |
22319086eb2232a9b18a65edaf0cc0b2
|
|
| BLAKE2b-256 |
d8575c8c649b1c9446553bf5b0cb74b04f502d21cf01ed2ba11df6563a84c993
|
Provenance
The following attestation bundles were made for quack_diff-0.0.5.tar.gz:
Publisher:
publish.yml on mattcristal/quack-diff
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quack_diff-0.0.5.tar.gz -
Subject digest:
84848ad1d60e489e3be582e7726f97bf98c2256c8cf47cefa09a228f4e210800 - Sigstore transparency entry: 886951512
- Sigstore integration time:
-
Permalink:
mattcristal/quack-diff@8458a41e58be1666cb37680a6f41c140325590bd -
Branch / Tag:
refs/tags/0.0.6 - Owner: https://github.com/mattcristal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8458a41e58be1666cb37680a6f41c140325590bd -
Trigger Event:
release
-
Statement type:
File details
Details for the file quack_diff-0.0.5-py3-none-any.whl.
File metadata
- Download URL: quack_diff-0.0.5-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6da7028d6804ed4cf6c01d5bc683a995338944b9c9540c8d2a81a0fce45496dd
|
|
| MD5 |
f1b763095bf01b326a0c69fa616e28c5
|
|
| BLAKE2b-256 |
1cea3933ff8745e8732d100525dff845cf853d1414076fea06f1d7c9af64d960
|
Provenance
The following attestation bundles were made for quack_diff-0.0.5-py3-none-any.whl:
Publisher:
publish.yml on mattcristal/quack-diff
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quack_diff-0.0.5-py3-none-any.whl -
Subject digest:
6da7028d6804ed4cf6c01d5bc683a995338944b9c9540c8d2a81a0fce45496dd - Sigstore transparency entry: 886951574
- Sigstore integration time:
-
Permalink:
mattcristal/quack-diff@8458a41e58be1666cb37680a6f41c140325590bd -
Branch / Tag:
refs/tags/0.0.6 - Owner: https://github.com/mattcristal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8458a41e58be1666cb37680a6f41c140325590bd -
Trigger Event:
release
-
Statement type: