Skip to content

Commit cc19f7b

Browse files
committed
feat: Add dqlens diff — compare two profiles
Compares the two most recent profiles and shows: - Tables added/removed - Row count changes with percentages - Columns added/removed - Column type changes, null rate drift, uniqueness changes - Min/max value shifts, pattern changes Includes text and JSON output formats. 24 unit tests covering: identical profiles, table add/remove, row count changes, column add/remove, type changes, null drift, uniqueness loss, value range shifts, pattern changes, edge cases, text formatting, JSON formatting. README: added diff command to commands table. Tracker: updated Phase 2 progress, test counts (303 total).
1 parent 910ab69 commit cc19f7b

4 files changed

Lines changed: 635 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ Every finding includes:
6262
| `dqlens run --focus high` | Only HIGH severity findings |
6363
| `dqlens run --ci` | Exit code 1 on failure (for CI/CD) |
6464
| `dqlens run --json-output` | Output as JSON |
65+
| `dqlens diff` | Compare two most recent profiles |
66+
| `dqlens diff --json-output` | Diff as JSON |
6567
| `dqlens ignore <key>` | Suppress a known finding |
6668

6769
## Python API

src/dqlens/cli.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
dqlens init — Initialize .dqlens/ directory with connection config
55
dqlens profile — Profile database tables and save baseline
66
dqlens run — Run tests against live database, show problems
7+
dqlens diff — Compare two profiles to see what changed
78
dqlens ignore — Suppress a known finding
89
"""
910

@@ -301,6 +302,44 @@ def run(
301302
sys.exit(1)
302303

303304

305+
@main.command()
306+
@click.option("--json-output", "json_out", is_flag=True, help="Output diff as JSON.")
307+
def diff(json_out: bool):
308+
"""Compare the two most recent profiles to see what changed.
309+
310+
Shows schema changes (tables/columns added/removed), row count
311+
shifts, null rate drift, uniqueness changes, and value range shifts.
312+
313+
Examples:
314+
dqlens diff
315+
dqlens diff --json-output
316+
"""
317+
from dqlens.baseline import load_latest_profile, load_previous_profile
318+
from dqlens.diff import diff_profiles, format_diff_json, format_diff_text
319+
320+
latest = load_latest_profile()
321+
previous = load_previous_profile()
322+
323+
if latest is None:
324+
click.echo("Error: No profiles found. Run 'dqlens profile' first.", err=True)
325+
sys.exit(1)
326+
327+
if previous is None:
328+
click.echo(
329+
"Error: Only one profile found. Run 'dqlens profile' again to "
330+
"create a second profile for comparison.",
331+
err=True,
332+
)
333+
sys.exit(1)
334+
335+
result = diff_profiles(before=previous, after=latest)
336+
337+
if json_out:
338+
print(json.dumps(format_diff_json(result), indent=2))
339+
else:
340+
click.echo(format_diff_text(result))
341+
342+
304343
@main.command()
305344
@click.argument("key")
306345
def ignore(key: str):

0 commit comments

Comments
 (0)