Docs & Code Guide

Databricks Unity Catalog diagram: system tables hold the object graph and the lineage

Unity Catalog does the bookkeeping most platforms make you reconstruct: every governed table and view sits in system.information_schema, and every read-write pair a query performed lands in the lineage system tables. A lakehouse diagram is therefore two queries and an API call away, and the interesting work is in what each source does and does not record.

7 min readFor lakehouse teams whose Databricks estate spans more catalogs than anyone can recite

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

205/20003 credits left
Try:

No account needed · Editable canvas, not a picture

system.information_schema spans every catalog

Each catalog carries an information_schema scoped to itself, and the system catalog carries one that spans the metastore: system.information_schema.tables lists every table and view Unity Catalog governs, across all catalogs, with type, owner, and timestamps. That single query is the node list, no per-catalog looping required, which is precisely what the per-dataset scoping in BigQuery makes you script around.

-- Nodes: everything Unity Catalog governs, all catalogs at once
SELECT table_catalog, table_schema, table_name, table_type
FROM system.information_schema.tables
WHERE table_catalog <> 'system';

-- Edges: reads and writes recorded from actual runs
SELECT DISTINCT source_table_full_name, target_table_full_name, entity_type
FROM system.access.table_lineage
WHERE event_date >= current_date() - INTERVAL 30 DAYS
  AND source_table_full_name IS NOT NULL
  AND target_table_full_name IS NOT NULL;

Lineage edges are recorded from real runs

system.access.table_lineage is not parsed from view definitions: rows are written when queries actually execute, whether from a notebook, a job, a pipeline, or a SQL warehouse, and the entity_type column says which. Column-level detail lives beside it in system.access.column_lineage. Edges earned from execution are more truthful than edges parsed from SQL text, because they capture notebooks and jobs that no view definition mentions.

The same property is the caveat: a path that has not run recently has no recent rows. Window the query too tightly and a monthly job's edges vanish from the diagram; window it too wide and long-deleted flows linger. Pick a window that covers your slowest real cadence, and treat an edge that ages out as a prompt to ask whether the flow still exists.

Jobs are your pipeline nodes

Tables alone make a warehouse map, not a platform map. The Jobs API, GET /api/2.1/jobs/list, returns every job with its schedule and tasks, and those are the moving parts readers ask about: what runs nightly, what writes gold, what breaks when a cluster is resized. Because table_lineage rows carry the entity that performed each read and write, you can join jobs to the tables they touch and draw each job as a node with its true inputs and outputs, rather than guessing from naming conventions.

Catalogs and schemas as zones, and the scheduled redraw

The catalog and schema hierarchy is the zoning: medallion layers as schemas within a catalog, or per-domain catalogs with bronze, silver, and gold inside each. Map the hierarchy onto nested zones and the diagram matches the access model your grants already enforce. The broader platform picture around it is covered in Databricks data platform diagrams.

The redraw is a scheduled job like any other on the platform: after your nightly pipelines complete, a job runs the queries above and hands the result to an agent connected to Datadef's MCP server, registry name io.datadef/mcp, which updates the diagram in place using an API key created in settings, on paid plans. Datadef does not connect to Databricks and does not poll the metastore; your job is the trigger and the agent call is the redraw. First diagram from a description instead: the Databricks diagram generator.

What the system tables miss

System tables are not on by default: an account admin has to enable the relevant schemas on the metastore before system.access.table_lineage returns anything. And lineage only covers what Unity Catalog governs, so a job writing to an external service or reading over JDBC from an outside database leaves no lineage row; those edges come from the job code, which an agent can read, not from the system tables.

The surface limits apply as everywhere: a live-embedded diagram requires the project shared public, which a governed lakehouse team may reasonably decline, and the loop maintains the diagram rather than the documentation prose around it.

FAQ

How do I visualize Unity Catalog objects and lineage in Databricks?

Two queries: system.information_schema.tables for every governed table and view across all catalogs, and system.access.table_lineage for read-write edges recorded from actual query runs. Draw catalogs and schemas as nested zones, tables as nodes, lineage pairs as arrows, and jobs from the Jobs API as the pipeline nodes between them.

Why is system.access.table_lineage empty in my workspace?

Usually because system table schemas have not been enabled: an account admin must enable them on the metastore before rows appear. If lineage exists but a specific flow is missing, check your time window, since lineage rows are written when queries execute, and a job that has not run inside the window contributes no edges.

Is Databricks lineage parsed from SQL definitions?

No, it is recorded from execution: when a notebook, job, pipeline, or warehouse query reads one table and writes another, that event produces lineage rows, with the performing entity identified. This captures flows no view definition mentions, and it also means a path that never runs never appears.

How should medallion layers appear on a Databricks diagram?

As the zone hierarchy Unity Catalog already encodes: bronze, silver, and gold as schemas inside a catalog, or per-domain catalogs each containing the three layers. Nesting zones to match the catalog.schema.table hierarchy keeps the diagram aligned with the grants and makes cross-layer arrows, the interesting ones, visually loud.

How does the diagram stay current as the lakehouse changes?

Through a scheduled Databricks job or CI task that reruns the system table queries after pipelines complete and asks an MCP-connected agent to update the diagram in place. Nothing watches the metastore automatically; the schedule is the trigger, and one agent call is the redraw.