Inspiration
Every data engineer has lived this: someone renames a column in a production table, and three dashboards silently break. Ownership is unclear, the impact is buried in dbt files and BI tools, and the tribal knowledge lives in one person's head. LLM agents can generate migration code, but without real context they hallucinate schemas and produce SQL that breaks on first run.
DataHub already holds the truth — schemas, lineage, ownership, view SQL. We built Data Change Autopilot to make an LLM agent use that truth.
What it does
A data engineer types a change in plain English (e.g. "rename email to contact_email"). Data Change Autopilot then:
- Reads DataHub for the real schema, lineage (table + column level), asset types, and view SQL
- Computes a deterministic impact score and risk level — explainable, reproducible, not produced by the LLM
- Generates the full migration — SQL for the source table, updated SQL for every downstream view/model, and rollback scripts
- Validates the code deterministically with SQLGlot against the DataHub schema
- Waits for human approval — nothing writes without a click
- Opens a real GitHub Pull Request — one clean commit, with the impact summary in the description
- Writes the change back into DataHub — column renamed in
schemaMetadata, lineage repointed to the new column URN, and an annotation added linking to the PR
The loop is closed: the next person, or the next agent, inherits the truth.
How we built it
Stack: Python 3.11 · FastAPI · LangChain · Google Gemini · DataHub Python SDK · DataHub GraphQL API · SQLGlot · Next.js 14 · TypeScript · Monaco Editor · Docker Compose · GitHub REST API
Architecture:
- The orchestrator uses the DataHub Python SDK (
DataHubGraph) for reads and writes on core aspects, and DataHub's GraphQLsearchAcrossLineagefor lineage traversal — the same API that powers DataHub's own UI - All impact scoring is pure Python — deterministic and reproducible
- All SQL validation runs through SQLGlot against schemas retrieved from DataHub — the LLM never validates its own output
- The write-back uses
read-modify-writeonschemaMetadata,upstreamLineage, andeditableSchemaMetadata, so we never blindly overwrite fields we didn't intend to touch
Challenges we ran into
The DataHub write-back was the hardest — and most rewarding — part. Three facts about DataHub's aspect model dictated the entire design:
UPSERTreplaces the entire aspect. Emitting a naive reconstructedschemaMetadatawould silently erase column types, descriptions, and the primary key. We had to read the existing aspect, mutate one field, and write it back.EditableSchemaFieldInfoClasshas no name field, so renames cannot be done through the editable layer. Renames must go throughschemaMetadataitself.PATCHexists forupstreamLineagebut not foreditableSchemaMetadata. For consistency (and to avoid subtle object-equality bugs in remove/add patches), we usedread-modify-writeeverywhere.
Renaming a field also changes its URN. DataHub cannot delete a
schemaField entity, so the old URN remains orphaned. We disclose
this honestly in the README rather than hide it.
Accomplishments we're proud of
- The write-back works and is verifiable. After approval, the column is really renamed in DataHub, the lineage really repoints, and the description really carries a link to the merged PR — visible in the DataHub UI.
- We have proof. 18 integration tests failed after the write-back precisely because the column they looked for no longer exists in the catalog. That failure is the best possible evidence that the write actually happened.
- 239 tests pass on host and in container, covering the full end-to-end path.
- The examples/ folder contains real generated outputs so judges can evaluate quality without running the project.
What we learned
- Metadata is only useful if agents use it and write to it. Reading is table stakes; contributing back is what closes the loop.
- Deterministic scoring + LLM reasoning + deterministic validation is a design pattern that scales beyond migrations.
read-modify-writeis boring and slow — and it is the right answer when the API is UPSERT-based.
What's next
- Wire the MCP Server into the orchestrator (currently scaffolded)
- Support column deletes and type changes end-to-end
- Contribute a new DataHub Skill for column-level change proposals
- Broaden connector coverage beyond the
showcase-ecommercedatapack
Built with
python, fastapi, langchain, google-gemini, datahub, graphql, sqlglot, nextjs, typescript, monaco-editor, docker, github-api
Built With
- datahub
- docker
- fastapi
- google-gemini
- graphql
- langchain
- monaco-editor
- nextjs
- python
- sqlglot
- typescript
Log in or sign up for Devpost to join the conversation.