【问题标题】:dbt macro to iterate over item in list within a sql call?dbt 宏在 sql 调用中迭代列表中的项目?
【发布时间】:2020-12-08 05:24:44
【问题描述】:

首先,我是 dbt 的支持者!我喜欢这个工具和它的多功能性。

在阅读一些docs 时,我注意到每次调用宏时我都可以对我的模式进行一些元工作。

其中之一是清理架构。

已根据 dbt slack 中的讨论进行了编辑

  1. dbt run-operation freeze 将内省所有将使用 dbt run 但使用自动生成的哈希(可能只是时间戳)写入的表。它会以我选择的模式输出这些表,并将“哈希”记录到控制台。

  2. dbt run-operation unfreeze --args '{hash: my_hash}' 然后继续查找使用该哈希前缀写入的表并将它们从架构中清除。

【问题讨论】:

  • 您能否详细说明您正在尝试使用run_query 做什么?您简要发送“清理”模式?你已经有一些内置的工具来迭代模式和表——例如grant_select_on_schemas,然后你可以把它放在一个 post run-hook 上。
  • 是的,我想做一些与grant_select_on_schemas 非常相似的事情,但我不想传入架构列表,而是在宏运行时拉取架构。跨度>
  • 好的——你能扩展一下吗?似乎我们可以构建一个宏来可能只是对模式中的所有表或所有模式中的所有表等执行该操作。
  • @gscott,我将原始帖子编辑为更简洁的用例 - 也许这可能更好地说明我的实际目标

标签: sql database list jinja2 dbt


【解决方案1】:

我在旧版本的 dbt 中创建了这样一个宏,它仍然适用于 0.17.1。

item_in_list_query 下方的宏正在从单独的宏 get_tables(也在下方)获取tables 的列表。然后将该表列表连接到item_in_list_query 中,以组成所需的 SQL 查询并执行它。为了演示,还有一个模型使用了item_in_list_query

item_in_list_query

{% macro item_in_list_query() %}

    {% set tables = get_tables() %}

    {{ log("Tables: " ~ tables, True) }}

    {% set query %}
        select id
        from my_tables
        {% if tables -%}
            where lower(table_name) in {% for t in tables -%} {{ t }} {%- endfor -%}
        {%- endif -%}
    {% endset %}

    {{ log("query: " ~ query, True) }}

    {# run_query returns agate.Table (https://agate.readthedocs.io/en/1.6.1/api/table.html). #}
    {% set results = run_query(query) %}

    {{ log("results: " ~ results, True) }}

    {# execute is a Jinja variable that returns True when dbt is in "execute" mode i.e. True when running dbt run but False during dbt compile. #}
    {% if execute %}
    {# agate.table.rows is agate.MappedSequence in which data that can be accessed either by numeric index or by key. #}
    {% set results_list = results.rows %}
    {% else %}
    {% set results_list = [] %}
    {% endif %}

    {{ log("results_list: " ~ results_list, True) }}
    {{ return(results_list) }}

{% endmacro %}

get_tables

{% macro get_tables() %}
      {%- set tables = [
          ('table1', 'table2')
      ] -%}
  {{return(tables )}}
{% endmacro %}

型号

{%- for item in item_in_list_query() -%}
  {%- if not loop.first %} UNION ALL {% endif %}
  select {{ item.id }}
{%- endfor -%}

【讨论】:

  • 这是金子 - 我将继续查看此内容,看看是否可以为我的用例构建您的示例。
猜你喜欢
  • 2022-10-04
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 2023-02-24
  • 1970-01-01
  • 2014-10-26
相关资源
最近更新 更多