Macros
Macros no DBT (Data Build Tool) são blocos de código reutilizáveis escritos em SQL e Jinja que podem ser chamados em diferentes modelos do projeto. Eles funcionam como funções que encapsulam lógicas complexas ou repetitivas, tornando o código mais limpo e manutenível.
https://docs.getdbt.com/docs/build/jinja-macros
Principais características das Macros¶
- Reutilização de código: Permite escrever uma lógica uma vez e reutilizá-la em vários modelos
- Parametrização: Aceita argumentos, tornando-as flexíveis e adaptáveis a diferentes contextos
- Modularidade: Facilita a manutenção do código ao centralizar lógicas comuns em um único lugar
Tipos comuns de Macros¶
Existem diferentes tipos de macros que podem ser utilizadas no DBT:
- Macros nativas: Fornecidas pelo próprio DBT, como current_timestamp() e generate_schema_name()
- Macros personalizadas: Criadas pelo usuário para atender necessidades específicas do projeto
- Macros de pacotes: Disponibilizadas através de pacotes dbt, como dbt_utils
Exemplo de Macro¶
{% macro first_letter_uppercase_explicit(column) %}
UPPER(LEFT({{ column }}, 1)) || LOWER(SUBSTRING({{ column }}, 2))
{% endmacro %}
Esta macro pode ser usada como no seguinte exemplo
SELECT
{{ first_letter_uppercase_explicit('first_name') }} as formatted_first_name,
{{ first_letter_uppercase_explicit('last_name') }} as formatted_last_name
FROM users
Veja que a coluna é passada como string, pois o compilador do DBT irá fazer a substituição textual do modelo e no target aparecerá como
SELECT
UPPER(LEFT(first_name, 1)) || LOWER(SUBSTRING(first_name, 2)) as formatted_first_name,
UPPER(LEFT(last_name, 1)) || LOWER(SUBSTRING(last_name, 2)) as formatted_last_name
FROM users
Macros presentes no projeto¶
As macros estão armazenadas no diretório macros/
dentro do projeto dbt/ipea
.
macros/
├── udfs/
│ ├── f_format_nc.sql
│ └── f_parse_dates.sql
├── create_udfs.sql
├── get_custom_schema.sql
└── parse_financial_value.sql
User-Defined-Functions (UDF)¶
À primeira vista UDFs e macros parecem ser substituíveis, porém a primeira possui um potencial muito maior quanto à complexidade. Caso a transformação tenha muitas etapas é recomendado usar UDF, mas sua utilização no DBT necessita algumas etapas extras. As UDFs ficam na pasta /udfs
, tendo o formato f_<nome da função>
. Aqui está um exemplo usado no projeto
{% macro create_f_format_nc() %}
create or replace function {{ target.schema }}.format_nc(in_text text)
returns text
as $$
with
pre_process as (
select left(in_text, 7) as prefix,
right(in_text, 4)::numeric as posfix
)
select concat(prefix, to_char(posfix, 'FM00000')) as result
from pre_process
$$
language sql
;
{% endmacro %}
Somente isso não é o suficiente para que os modelos possam utilizá-la, para isso criamos a macro create_udfs.sql
, que inicializa as funções e as deixam prontas para uso
{% macro create_udfs() %}
create schema if not exists {{ target.schema }};
{{ create_f_parse_dates() }}
;
{{ create_f_format_nc() }}
;
{% endmacro %}
No arquivo dbt_project.yml
foi adicionado a seguinte configuração:
Isso irá criar as funções sempre quando um modelo for executado.