dbt logo

The Rename You Didn't Make

There is a column in your project called `status`, and you have wanted to rename it for about eight months. It should be `order_status` — everyone agrees. You have not done it.

The Rename You Didn't Make

There is a column in your project called status, and you have wanted to rename it for about eight months. It should be order_status — everyone agrees. You have not done it.

Not because it's hard. Because you don't know what will break.

You know the model-level story. dbt ls --select fct_orders+ lists what depends on the model, and that part works. What it cannot tell you is the part you actually hesitate over: whether the values in that column are the same values four other models test against, whether anything outside the dbt project reads it, whether the meaning of the column is written down anywhere someone else relies on, and — most practically — who you would even ask.

So the rename stays on the list. It's a small piece of technical debt that is permanently one unknown away from being paid off.

The question dbt is not shaped to answer

This isn't a gap in dbt's lineage. dbt's lineage is excellent at what it describes: the dependency graph of models inside the project, derived from ref and source. That graph is real, complete within its boundary, and correct.

The boundary is the point. Three things live outside it.

Concept-level relationships. Your status column tests against a list of permitted values. So does the status column on stg_returns, and on two staging models nobody has looked at in a year. Those four lists describe one concept, but dbt sees four unrelated string arrays. Nothing connects them, so nothing can tell you that renaming here has implications there.

Consumers who never had a ref. The reverse-ETL job syncing that mart to your CRM. The ML pipeline that trained on it. The service another team wrote against the warehouse directly. None of them appear in dbt ls, because none of them are dbt. They will discover your rename in production.

Who to ask. dbt groups and model owners tell you who maintains the SQL file. They do not tell you who decided what the column means, or who should be consulted before that meaning changes. Those are often not the same person, and the second one is the one you need.

What a real answer looks like

Ask a column, a vocabulary or a model what depends on it, and get back four things.

Where it is used inside the governed model. Which types hold this element, which vocabulary governs its values, what it references, and — if you ask about a vocabulary — every column whose values come from it. That last one is the answer nobody has today: a vocabulary reaches a model only through the columns it governs, so a term change has a blast radius the vocabulary itself records nothing about.

Which estates carry it, and by what path. Not just "this is in dbt", but whether the concept is carried directly or reached through the type that holds it. The distinction matters: "this column is in the warehouse" and "this vocabulary reaches the warehouse through these three columns" are different facts, and conflating them produces confident wrong answers.

What it means externally. If the column is bound to a public term, that binding is its identity outside your company — and anyone consuming it against that identity is relying on the binding, not on your column name.

Which serializations it travels into. If the governed model publishes as JSON Schema for an API team or a contract for a partner, the column is in those artifacts too.

The honest shape of it

Two things worth saying plainly, because an impact tool that overstates itself is worse than none.

It answers from what is governed. A consumer nobody ever wrote down is still invisible — the tool cannot know about a Python script on someone's laptop. What it changes is that the consumers you have recorded stop living in one person's memory. The recipe gives you somewhere to record them, which is the prerequisite, not an afterthought.

It is a question you ask, not an alarm that fires. The pull direction is deliberate. A person about to change a definition is already motivated and already paying attention; that is the right moment for this information. A notification arriving while you are doing something else is an interruption you will learn to ignore.

What changes about the rename

You ask before you touch it. The answer comes back: the vocabulary is shared with three other models, the concept is bound to a public term, one mart carrying it is consumed by a reverse-ETL job, and the person who owns the definition is named.

Now the rename is a twenty-minute task with a list, instead of an eight-month hesitation. And the list is the thing — not because it is long, but because it is finite and written down.

The other half is that the next person doesn't have to rediscover any of it.

The dbt quickstart that ships with the CoreModels integration docs walks the import and the first questions end to end.