Metacenta

Maintainability · rule select-star

select * in dbt models

A Metacenta review checks this under the rule Models select explicit columns. Everything below applies whether or not you ever commission one.

What this rule checks

This rule flags dbt models whose output projects an upstream model, source or table with * and no column list on the way. We follow the * from the final select through CTEs. select * from final, where final lists its columns, passes. So does an import CTE over ref() that a later CTE narrows.

Why it matters

An upstream column added or renamed changes this model's output without any code change or test failure. Downstream models and dashboards see the change before anyone has reviewed it.

How to fix it

Replace select * with explicit column lists. List the columns explicitly, at least at the layer boundary. Keep the import-CTE style if you use it, and name the columns in the CTE the final select reads.

Before:

with orders as (
    select * from {{ ref('stg_orders') }}
)

select * from orders

After:

with orders as (
    select * from {{ ref('stg_orders') }}
),

final as (
    select order_id, customer_id, ordered_at
    from orders
)

select * from final

When it is fine to leave

A model whose job is to mirror its input, such as a thin wrapper that exists only to give a table a stable name, can keep *. So can a staging model over a source whose every new column should flow through. Say so in the model's description.

What we need to check it

manifest.json with each model's raw_code. We tokenise the Jinja-templated SQL rather than parse it, so the finding is medium confidence. We decline when no model carries raw_code.