Inspiration
Every data team has shipped a rename that looked like housekeeping and broke a report someone presents to executives. The reviewer isn't careless — they're reading a diff, and a diff cannot show you that a column feeds a Looker dashboard six hops downstream.
DataHub already knows the answer. It just isn't in the pull request, which is where the decision actually gets made. We wanted to move that knowledge to the moment it matters.
What it does
Open a pull request that renames a column in a dbt model. Blast Radius comments with what actually breaks:
This change breaks 1 dashboard, 2 charts, and 16 tables. Traced
orders.order_datethrough DataHub lineage: 21 downstream entities across 7 platforms, up to 6 hops deep.
It names them — Order Entry Dashboard in Looker, Orders By Month in Tableau, five PowerBI measure tables — and names the humans who own each one, ranked by how much of their surface is affected.
Then it writes the verdict back into DataHub as an institutional-memory link and a HighBlastRadius tag, so the next engineer or agent inherits the finding instead of rediscovering it.
It also generates the migration: a backwards-compatible alias first, then consumers in dependency order, each attributed to its owner.
Severity that actually discriminates
A reviewer who sees a red banner on every pull request stops reading them. Severity is driven by what breaks, not how much:
| Level | Trigger | Example |
|---|---|---|
| CRITICAL | A dashboard or ML model consumes the column | orders.order_date |
| HIGH | A chart renders it | orders.order_id |
| MEDIUM | Only derived tables and replication jobs | customers.nls_language |
| LOW | Nothing downstream depends on it | — |
How we built it
- Parse the PR diff for column-level schema changes — renames, drops, type changes. Handles dbt
.sqlmodels andschema.yml, and dedupes a rename that touches both. - Resolve each changed column to its DataHub
schemaFieldURN. - Query
searchAcrossLineagedownstream across degrees1,2,3+. - Classify casualties, resolve owners via the ownership aspect.
- Render a markdown comment and post it with
gh pr comment. - Write the verdict back with
addLink+createTag/addTag.
Python 3.9+, requests, GitHub CLI. Tested against DataHub v1.7.0 quickstart with the showcase-ecommerce datapack.
Challenges we ran into
The severity model rated everything HIGH. Our first version keyed severity partly on how many platforms a column touched. In a real warehouse every column crosses three or more platforms, so every change came back red. We rebuilt it around what breaks rather than how much. The MEDIUM verdict now states the absence of BI impact explicitly, because a reviewer has to trust the quiet ratings as much as the loud ones.
A typo reported "Safe to merge." An absent column and an unused column look identical in the lineage graph — both return zero downstream entities. That is the one wrong answer this tool must never give, so it now validates against the schema first and lists the real columns.
A bug in the DataHub Python SDK. client.lineage.get_lineage() calls DatasetUrn.from_string() on the parent of every schema field in the returned paths. The Tableau connector legitimately emits chart-parented schema fields, so any column whose lineage reaches a chart raises InvalidUrnError — and one unparseable entry discards the entire result set. That is exactly the set of columns worth analysing. We located the defect, verified raw GraphQL returns all results, and reported it upstream with a reproduction and a suggested fix: datahub-project/datahub#18964
Accomplishments that we're proud of
The tool discriminates. Run it on orders.order_date and it's critical; run it on customers.nls_language in the same warehouse and it's medium, with the reason stated. That distinction is the difference between a bot people act on and a bot people mute.
And the write-back is real, not decorative — the verdict is queryable in DataHub after every run, and it's idempotent, so running on every push doesn't pile up duplicates.
What we learned
Reading metadata is the easy half. The value compounds only when findings go back into the graph, and getting that right meant handling the unglamorous parts — duplicate links, stale verdicts, entities that legitimately have no owner.
We also learned to distrust our own severity ratings until we'd tested the boring case. A tool that's right about the scary column and wrong about the safe one is worse than no tool.
What's next for Blast Radius
- A GitHub Action so it runs on every PR without local setup
- Support for dbt's
manifest.jsonfor precise model resolution - ML lineage: the same analysis for feature tables and model inputs
- Upstream the SDK fix as a PR, not just an issue
Log in or sign up for Devpost to join the conversation.