Crear tu Primer Modelo SQL con Jinja

Video
25 min~5 min lectura

Reproductor de video

Concepto clave

En dbt, un modelo es un archivo SQL que transforma datos de tu warehouse. La magia viene con Jinja, un motor de plantillas que permite escribir SQL dinámico. Piensa en Jinja como las fórmulas en Excel: en lugar de escribir cada celda manualmente, defines reglas que se aplican automáticamente.

Por ejemplo, imagina que tienes ventas de 50 países. Sin Jinja, escribirías 50 consultas similares. Con Jinja, escribes una sola plantilla que genera las 50 automáticamente. Esto no solo ahorra tiempo, sino que reduce errores y hace tu código más mantenible.

Cómo funciona en la práctica

Vamos a crear un modelo que limpia datos de usuarios. Supón que tu tabla raw tiene columnas como user_id, signup_date, y country, pero algunos valores están sucios o faltan. El proceso es:

  1. Define la fuente de datos usando {{ ref() }} para referenciar otros modelos.
  2. Aplica transformaciones con funciones SQL y lógica condicional de Jinja.
  3. Guarda el resultado como una nueva tabla o vista en tu warehouse.

En dbt Cloud, esto se hace en el editor SQL, donde escribes el código y luego ejecutas dbt run para materializarlo. La clave es que Jinja se procesa antes de que el SQL llegue al warehouse, generando SQL puro que tu motor de datos puede ejecutar.

Codigo en accion

Aquí tienes un ejemplo básico de un modelo SQL con Jinja. Primero, el código sin Jinja (estático):

SELECT
    user_id,
    UPPER(country) AS country_clean,
    signup_date
FROM raw_users
WHERE signup_date >= '2023-01-01'

Ahora, refactorizado con Jinja para hacerlo dinámico y reutilizable:

{{ config(materialized='table') }}

WITH raw_data AS (
    SELECT *
    FROM {{ ref('raw_users') }}
)

SELECT
    user_id,
    {% if target.name == 'dev' %}
        'TEST' AS country_clean  -- En desarrollo, usa un valor fijo
    {% else %}
        UPPER(country) AS country_clean  -- En producción, transforma
    {% endif %},
    signup_date
FROM raw_data
WHERE signup_date >= '{{ var("start_date", "2023-01-01") }}'

Este código usa {{ ref() }} para referenciar el modelo raw_users, {{ config() }} para definir cómo se materializa, y {{ var() }} para usar variables configurables. La cláusula {% if %} cambia el comportamiento según el entorno (dev vs. prod).

Errores comunes

  • Olvidar cerrar bloques Jinja: Cada {% ... %} debe tener su {% end... %}. Si no, dbt fallará al compilar. Revisa siempre la estructura de tus condicionales y bucles.
  • Usar Jinja dentro de strings SQL: Jinja no procesa dentro de comillas simples. Por ejemplo, '{{ var("date") }}' puede no funcionar como esperas; mejor usa {{ var("date") }} directamente en la consulta.
  • No probar en múltiples entornos: El código que funciona en dev puede fallar en prod si usas {{ target.name }} incorrectamente. Siempre prueba con dbt run --target prod en un entorno seguro.
  • Ignorar el orden de ejecución: dbt ejecuta modelos basado en dependencias definidas por {{ ref() }}. Si tu modelo depende de otro que no existe, fallará. Usa dbt docs generate para visualizar el grafo de dependencias.

Checklist de dominio

  • Puedo escribir un modelo SQL que use {{ ref() }} para referenciar otros modelos.
  • Sé cómo usar {{ config() }} para configurar materialización (table, view, incremental).
  • Implemento lógica condicional con {% if %} para diferentes entornos (ej., dev vs. prod).
  • Utilizo variables con {{ var() }} para hacer mi código configurable.
  • Verifico que mi código Jinja se compile correctamente con dbt compile antes de ejecutar.
  • Entiendo cómo dbt procesa Jinja para generar SQL estándar que ejecuta mi warehouse.
  • Puedo identificar y corregir errores comunes de sintaxis en bloques Jinja.

Crear un modelo de limpieza de pedidos con Jinja

En este ejercicio, practicarás creando un modelo en dbt Cloud que transforma datos de pedidos crudos (raw_orders) usando Jinja. Sigue estos pasos:

  1. Abre dbt Cloud y navega al editor SQL. Crea un nuevo archivo llamado cleaned_orders.sql en la carpeta models.
  2. Define el modelo para materializarse como una tabla usando {{ config() }}.
  3. Usa {{ ref('raw_orders') }} para referenciar la tabla de pedidos crudos. Asegúrate de que raw_orders existe en tu proyecto (puede ser un modelo de ejemplo).
  4. Selecciona las columnas: order_id, customer_id, order_date, y amount. Agrega una columna calculada llamada amount_usd que convierta amount a dólares si la moneda original es euros (usa un tipo de cambio fijo de 1.1). Usa Jinja para hacer esto condicional: si currency = 'EUR', multiplica por 1.1; de lo contrario, deja amount como está.
  5. Filtra los pedidos para incluir solo aquellos desde una fecha configurable con una variable. Usa {{ var('start_date', '2023-01-01') }} como valor por defecto.
  6. Ejecuta dbt run en dbt Cloud para materializar el modelo. Verifica en tu warehouse que la tabla cleaned_orders se creó correctamente.
  7. Opcional: Modifica el modelo para usar {{ target.name }} y en el entorno de desarrollo (dev), limita los resultados a 100 filas para pruebas rápidas.
Pistas
  • Recuerda que Jinja se escribe entre {% ... %} para lógica y {{ ... }} para variables. Usa un bloque IF para la conversión de moneda.
  • Puedes probar tu variable start_date ejecutando dbt run --vars '{start_date: 2024-01-01}' en la línea de comandos de dbt Cloud.
  • Si tienes errores de compilación, usa dbt compile para ver el SQL generado y depurar problemas de sintaxis Jinja.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.