Uno de los aspectos que ha contribuido al enorme crecimiento de dbt en los últimos años es su capacidad para combinar SQL con herramientas propias del desarrollo de software. Gracias a esta integración, los equipos de datos pueden construir proyectos más mantenibles, reutilizables y fáciles de escalar.
Dentro de este ecosistema, Jinja desempeña un papel fundamental.
Aunque muchos usuarios comienzan utilizando únicamente las funcionalidades más básicas, a medida que los proyectos crecen resulta necesario aprovechar capacidades más avanzadas para evitar duplicaciones, automatizar tareas repetitivas y simplificar el mantenimiento del código.
En este artículo continuaremos explorando Jinja desde un nivel intermedio, analizando algunas de las funcionalidades más utilizadas en proyectos dbt modernos.
¿Qué es Jinja?
Jinja es un motor de plantillas que permite generar código dinámicamente.
En el contexto de dbt, se utiliza para añadir lógica a los modelos SQL mediante:
- Variables.
- Condicionales.
- Bucles.
- Macros.
- Funciones reutilizables.
Gracias a Jinja, el SQL deja de ser completamente estático y puede adaptarse automáticamente a diferentes escenarios.
Por ejemplo:
SELECT *
FROM {{ ref(‘customers’) }}
Aunque parece una consulta SQL normal, la función ref() es procesada previamente por Jinja antes de ejecutarse en el Data Warehouse.
¿Por qué utilizar Jinja?
A medida que los proyectos crecen, es habitual encontrar patrones repetitivos.
Por ejemplo:
- Listas de columnas similares.
- Transformaciones repetidas.
- Reglas de negocio comunes.
- Generación de métricas.
Sin una herramienta adecuada, esto puede provocar una gran cantidad de código duplicado.
Jinja ayuda a resolver este problema mediante la automatización y reutilización de lógica.
Variables en Jinja
Las variables permiten almacenar valores reutilizables.
Por ejemplo:
{% set country = ‘Spain’ %}
Posteriormente pueden utilizarse dentro de una consulta:
SELECT *
FROM customers
WHERE country = ‘{{ country }}’
Este enfoque facilita la modificación de parámetros sin necesidad de actualizar múltiples líneas de código.
Trabajando con listas
Las listas son especialmente útiles cuando necesitamos procesar varios elementos de forma repetitiva.
Por ejemplo:
{% set metrics = [
‘sales’,
‘profit’,
‘cost’
] %}
Esta estructura puede utilizarse posteriormente para generar SQL dinámicamente.
Utilizando bucles
Los bucles son una de las funcionalidades más potentes de Jinja.
Permiten generar múltiples líneas de SQL a partir de una única definición.
Por ejemplo:
{% for metric in metrics %}
SUM({{ metric }}) AS total_{{ metric }}
{% endfor %}
Esto evita tener que escribir manualmente cada columna.
En proyectos grandes, esta capacidad reduce considerablemente la cantidad de código.
Generando métricas dinámicamente
Supongamos que necesitamos calcular varias métricas similares.
Sin Jinja:
SELECT
SUM(sales) AS total_sales,
SUM(profit) AS total_profit,
SUM(cost) AS total_cost
FROM orders
Con Jinja:
{% set metrics = [
‘sales’,
‘profit’,
‘cost’
] %}
SELECT
{% for metric in metrics %}
SUM({{ metric }}) AS total_{{ metric }}
{% if not loop.last %},{% endif %}
{% endfor %}
FROM orders
El resultado final será exactamente el mismo, pero el código resulta mucho más flexible.
Condicionales en Jinja
Los condicionales permiten modificar el comportamiento del código dependiendo de determinadas condiciones.
Por ejemplo:
{% if target.name == ‘prod’ %}
WHERE active = TRUE
{% endif %}
Esto resulta muy útil cuando se trabaja con distintos entornos.
Por ejemplo:
- Desarrollo.
- Testing.
- Producción.
Cada entorno puede ejecutar lógica diferente sin necesidad de mantener múltiples versiones del mismo modelo.
Uso de target en dbt
Una variable muy utilizada dentro de dbt es target.
Permite conocer información sobre el entorno donde se está ejecutando el proyecto.
Por ejemplo:
{{ target.name }}
Puede devolver valores como:
dev
test
prod
Gracias a esta información es posible adaptar el comportamiento de los modelos según el contexto.
Introducción a las macros
Las macros representan uno de los conceptos más importantes dentro de Jinja y dbt.
Una macro funciona de manera similar a una función en programación.
Por ejemplo:
{% macro aplicar_descuento(precio) %}
{{ precio }} * 0.9
{% endmacro %}
Posteriormente:
{{ aplicar_descuento(‘importe’) }}
Esto permite encapsular lógica reutilizable y mantener los proyectos mucho más organizados.
Beneficios de utilizar macros
Las macros aportan múltiples ventajas.
Reutilización
La lógica se escribe una única vez.
Consistencia
Todos los modelos utilizan exactamente las mismas reglas.
Mantenimiento simplificado
Si una regla cambia, basta con modificar la macro.
Menos errores
Se reduce la duplicación de código.
Uso de filtros
Jinja incorpora filtros que permiten transformar valores.
Por ejemplo:
{{ «analytics» | upper }}
Resultado:
ANALYTICS
También existen otros filtros útiles para:
- Convertir texto.
- Manipular listas.
- Formatear valores.
- Limpiar cadenas.
Aunque suelen utilizarse menos que las macros o los bucles, pueden resultar muy prácticos en determinados escenarios.
Organización de proyectos complejos
Cuando un proyecto dbt crece, el uso adecuado de Jinja se vuelve especialmente importante.
Los equipos suelen utilizarlo para:
- Generar modelos repetitivos.
- Gestionar configuraciones.
- Automatizar transformaciones.
- Centralizar reglas de negocio.
Esto ayuda a mantener una estructura ordenada incluso cuando existen cientos de modelos.
Casos de uso habituales
Las capacidades de Jinja aparecen en numerosos escenarios reales.
Generación automática de columnas
Muy útil cuando existen decenas de métricas similares.
Reglas de negocio reutilizables
Permite centralizar cálculos utilizados en múltiples modelos.
Adaptación por entornos
Facilita diferencias entre desarrollo y producción.
Automatización de SQL repetitivo
Reduce considerablemente la duplicación de código.
Estandarización
Ayuda a aplicar criterios homogéneos dentro de toda la plataforma analítica.
Buenas prácticas al utilizar Jinja
Aunque Jinja es extremadamente potente, conviene utilizarlo con moderación.
Mantener la legibilidad
El objetivo es simplificar el código, no hacerlo más difícil de entender.
Evitar lógica excesivamente compleja
Si una plantilla resulta más difícil de leer que el SQL original, probablemente conviene replantear la solución.
Documentar macros importantes
Las macros suelen convertirse en componentes críticos del proyecto.
Reutilizar componentes
Evitar copiar y pegar lógica repetida.
Aplicar estándares comunes
La consistencia facilita la colaboración entre equipos.
Jinja y Analytics Engineering
El crecimiento del Analytics Engineering ha impulsado enormemente la adopción de Jinja.
Los Analytics Engineers utilizan estas capacidades para:
- Crear modelos escalables.
- Reducir duplicaciones.
- Mantener consistencia.
- Automatizar procesos repetitivos.
Gracias a esta combinación de SQL y plantillas dinámicas, dbt permite aplicar principios propios de la ingeniería de software al mundo analítico.
El equilibrio entre SQL y Jinja
Una de las recomendaciones más habituales dentro de la comunidad dbt es encontrar un equilibrio adecuado.
No todo debe resolverse con Jinja.
En muchos casos, SQL simple y bien estructurado resulta más fácil de mantener.
Jinja debe utilizarse cuando realmente aporta:
- Reutilización.
- Automatización.
- Escalabilidad.
- Mantenimiento simplificado.
Cuando se aplica correctamente, se convierte en una herramienta extraordinariamente potente.
Conclusión
Jinja es una de las piezas clave que hacen de dbt una herramienta tan poderosa para los equipos modernos de datos. Gracias a sus variables, bucles, condicionales y macros, permite generar SQL dinámico, reducir duplicaciones y construir proyectos mucho más mantenibles.
A medida que las plataformas analíticas crecen, la capacidad de reutilizar lógica y automatizar tareas repetitivas se vuelve cada vez más importante. Dominar Jinja no solo mejora la productividad, sino que también ayuda a aplicar buenas prácticas de ingeniería dentro del ecosistema de datos.
Para cualquier profesional que trabaje con dbt, aprender a utilizar Jinja de forma efectiva representa un paso fundamental hacia la construcción de proyectos analíticos más robustos, escalables y fáciles de mantener.




