Jinja 是一个高效、功能强大的模板引擎,广泛用于生成动态内容。它允许在多种基于文本的格式(如 HTML、XML、CSV 或 LaTex)中嵌入编程逻辑。欲了解更多信息,请参阅:Jinja 文档 。
在现代数据工程中,Jinja 因为能够在 SQL 转换中支持变量、逻辑和重用性,尤其在 dbt 等开源工具中的集成,已经成为一种流行的选择。
Recurve 与 dbt 深度集成,支持在 SQL 模型中直接使用 Jinja,且允许定义可重用的元素,如变量、宏和数据测试。
Jinja 语法
Jinja 的语法与 Python 类似,代码通常位于特定的分隔符标签内,主要包括以下几种:
表达式 {{ ... }}:
用于输出字符串、引用变量和调用宏。
语句 {% ... %}
:用于控制流(如 for
循环和 if
语句),也用于定义宏。
注释 {# ... #}
:注释内容,编译时会被忽略。
以下是一些在 Recurve SQL 模型中使用 Jinja 的示例。
设置变量
Recurve 支持创建全局变量,这些变量可以在多个模型和数据管道中重复使用。详情请查阅文档:变量
SQL 模型 编译代码
在 Jinja 中,您可以按照以下方式定义局部变量:
Copy -- min_rental_duration = 3, defined in the Variables section
SELECT film_id, title, rental_duration
FROM film
WHERE rental_duration >= {{ var ( 'min_rental_duration' ) }}
Copy SELECT film_id, title, rental_duration
FROM film
WHERE rental_duration >= 3
if
语句
SQL 模型 编译代码
用 if
语句来检查条件:
Copy {% set include_r_rated = true %}
SELECT film_id, title, rating
FROM film
WHERE 1 = 1
{% if include_r_rated %}
AND rating = 'R'
{% else %}
AND rating != 'R'
{% endif %}
Copy SELECT film_id, title, rating
FROM film
WHERE 1 = 1
AND rating = 'R'
for
循环
SQL 模型 编译代码
用 for
循环来遍历一个列表或字典:
Copy {% set categories = ['Action', 'Comedy', 'Drama'] %}
SELECT f.film_id, f.title, c.name AS category
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id
WHERE c.name IN (
{% for category in categories %}
'{{ category }}' {% if not loop.last %},{% endif %}
{% endfor %}
)
Copy SELECT f.film_id, f.title, c.name AS category
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id
WHERE c.name IN (
'Action' ,
'Comedy' ,
'Drama'
)
定义宏
Jinja 宏类似于编程语言中的函数。你可以将逻辑和转换定义为宏,并在不同的模型中复用它。请参考: 宏 。
Macro 定义 SQL 模型 编译代码
宏的定义:
Copy {% macro get_actor_films(actor_id) %}
SELECT f.film_id, f.title
FROM film f
JOIN film_actor fa ON f.film_id = fa.film_id
WHERE fa.actor_id = {{ actor_id }}
{% endmacro %}
在模型中调用宏:
Copy WITH actor_films AS (
{{ get_actor_films( 1 ) }}
)
SELECT *
FROM actor_films
Copy WITH actor_films AS (
SELECT f.film_id, f.title
FROM film f
JOIN film_actor fa ON f.film_id = fa.film_id
WHERE fa.actor_id = 1
)
SELECT *
FROM actor_films
内置 Jinja 函数
由于 Recurve 集成了开源的 dbt 框架,因此也可以使用 dbt 特定的内置 Jinja 函数。有关函数的完整列表和定义,可以参考 dbt Jinja 函数文档 。
以下是一些常用的函数:
ref()
功能: 引用同一项目或跨项目的其他模型。此函数确保依赖关系得到正确管理。
用法 : {{ ref('model_name') }}
source()
功能: 在模型和源表之间建立依赖关系,帮助更好地追踪数据血缘。
用法 : {{ source('source_name', 'table_name') }}
var()
功能: 访问“项目库 /Library ”中定义的变量,支持模型和宏的参数化。请查阅:变量 。
用法 : {{ var('variable_name') }}