A macro is a reusable Jinja function defined in macros/*.sql that generates SQL (or snippets) for models, tests, and hooks.
Example
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name) %}
({{ column_name }} / 100.0)
{% endmacro %}Use it:
select
order_id,
{{ cents_to_dollars('amount_cents') }} as amount
from {{ ref('stg_orders') }}When macros help
- Repeated expressions (surrogate keys, standardized timestamps)
- Adapter-specific SQL differences (
dateaddvsdate_add) - Custom generic tests
- DRY patterns shared across many models
When macros hurt
- Hiding simple SQL behind opaque layers beginners cannot read
- Business logic that should be an intermediate model instead
- Over-abstracted frameworks nobody can debug
Mental model
macro = function that returns SQL text at compile time model = dataset definition executed in the warehouse
Interview tip: "I extract a macro after the third copy-paste, and I keep business grain as models, not as nested macros."