dremio dbt 模型处理简单说明
dremio dbt 配置
一个参考配置,可以看到我们需要对象存储的信息,以及space 信息(当然也可以全部使用nessie 进行纳管)
dremio:
outputs:
dev:
password: <password>
port: <port>
software_host: <host>
object_storage_source: s3 # s3 source
object_storage_path: dbt # 建议s3 bucket
dremio_space: nessie # nessie 的source
dremio_space_folder: dbtv2.biz # nessie 的folder
threads: 3
type: dremio
use_ssl: false
user: <user>
target: dev
database 以及schema 的调整
进行了重写,会基于配置的信息(对象存储以及space), 主要是基于dbt 的macro
database 的处理
{% macro dremio__generate_database_name(custom_database_name=none, node=none) -%}
{%- set default_database = target.database if not is_datalake_node(node)
else target.datalake -%}
{%- set custom_database_name = custom_database_name if not is_datalake_node(node)
else node.config.datalake -%}
{{ generate_database_name_impl(default_database, custom_database_name, node) }}
{%- endmacro %}
{% macro generate_database_name_impl(default_database, custom_database_name=none, node=none) -%}
{%- if custom_database_name is none -%}
{{ default_database }}
{%- else -%}
{{ custom_database_name }}
{%- endif -%}
{%- endmacro %}
schema 类似
实际对象存储中的数据才是我们可以进行实际操作的(比如crud),当然实际使用的业务数据可以通过source 配置
物化处理
物化实际上包含了多种模式比如view,table,当然dremio 还支持自己特有的反射,对于view 以及table 的处理dremio 使用了
多次执行模式(不像传统adapter),先是在对象存储中创建一个必须的,然后是在space 中创建对应的vds ,view 模式的与dbt
的类似,对于table 模式的会先按照类似dbt 的物化表模式,然后同时还会创建一个vds,dremio dbt 中的macro
- view 处理
{% materialization view, adapter='dremio' %}
{%- set identifier = model['alias'] -%}
{%- set twin_strategy = config.get('twin_strategy', validator=validation.any[basestring]) or 'clone' -%}
{%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}
{%- set exists_as_view = (old_relation is not none and old_relation.is_view) -%}
{%- set target_relation = api.Relation.create(
identifier=identifier, schema=schema, database=database, type='view') -%}
{% set grant_config = config.get('grants') %}
{{ run_hooks(pre_hooks) }}
-- If there's a table with the same name and we weren't told to full refresh,
-- that's an error. If we were told to full refresh, drop it. This behavior differs
-- for Snowflake and BigQuery, so multiple dispatch is used.
{%- if old_relation is not none and old_relation.is_table -%}
{{ handle_existing_table(should_full_refresh(), old_relation) }}
{%- endif -%}
-- build model
{% call statement('main') -%}
{{ create_view_as(target_relation, external_query(sql)) }}
{%- endcall %}
# 应用策略
{{ apply_twin_strategy(target_relation) }}
{{ enable_default_reflection() }}
{% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}
{{ run_hooks(post_hooks) }}
{{ return({'relations': [target_relation]}) }}
{% endmaterialization %}
- table
实际上与view 类似
{% materialization table, adapter = 'dremio' %}
{%- set identifier = model['alias'] -%}
{%- set format = config.get('format', validator=validation.any[basestring]) or 'iceberg' -%}
{%- set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) -%}
{%- set target_relation = api.Relation.create(identifier=identifier,
schema=schema,
database=database,
type='table') -%}
{% set grant_config = config.get('grants') %}
{{ run_hooks(pre_hooks) }}
-- setup: if the target relation already exists, drop it
-- in case if the existing and future table is delta, we want to do a
-- create or replace table instead of dropping, so we don't have the table unavailable
{% if old_relation is not none -%}
{{ adapter.drop_relation(old_relation) }}
{%- endif %}
-- build model
{% call statement('main') -%}
{{ create_table_as(False, target_relation, external_query(sql)) }}
{%- endcall %}
{{ refresh_metadata(target_relation, format) }}
{{ apply_twin_strategy(target_relation) }}
{% do persist_docs(target_relation, model) %}
{% do apply_grants(target_relation, grant_config, should_revoke=should_revoke) %}
{{ run_hooks(post_hooks) }}
{{ return({'relations': [target_relation]})}}
{% endmaterialization %}
apply_twin_strategy 对于dremio 的table 模式物化很重要,处理如下,当然view 也是会执行这个的
{%- macro apply_twin_strategy(target_relation) -%}
{%- set twin_strategy = config.get('twin_strategy', validator=validation.any[basestring]) or 'clone' -%}
{%- if target_relation.type == 'view' -%}
{%- if twin_strategy != 'allow' -%}
{%- set table_relation = api.Relation.create(
identifier=generate_alias_name_impl(model.name, config.get('file', validator=validation.any[basestring]), model),
schema=generate_schema_name_impl(target.root_path, config.get('root_path', validator=validation.any[basestring]), model),
database=generate_database_name_impl(target.datalake, config.get('datalake', validator=validation.any[basestring]), model),
type='table') -%}
{{ adapter.drop_relation(table_relation) }}
{%- endif -%}
{%- elif target_relation.type == 'table' -%}
{%- if twin_strategy in ['prevent', 'clone'] -%}
{%- set view_relation = api.Relation.create(
identifier=generate_alias_name_impl(model.name, config.get('alias', validator=validation.any[basestring]), model),
schema=generate_schema_name_impl(target.schema, config.get('schema', validator=validation.any[basestring]), model),
database=generate_database_name_impl(target.database, config.get('database', validator=validation.any[basestring]), model),
type='view') -%}
{%- if twin_strategy == 'prevent' -%}
{{ adapter.drop_relation(view_relation) }}
{%- elif twin_strategy == 'clone' -%}
{%- set sql_view -%}
select *
from {{ render_with_format_clause(target_relation) }}
{%- endset -%}
{% call statement('clone_view') -%}
# 对于table 模式的关系会进行vds 的创建,这个也是我们看到的尽管是物化table,但是模型都会在一个space 中
{{ create_view_as(view_relation, sql_view) }}
{%- endcall %}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
说明
dremio dbt adapter 在处理上重写了不少dbt macro,确保创建的模型都会在space 中存在,对于数据的物化是在对象存储中的,比较符合dremio 的玩法,当然对于基于了nessie catalog 数据源,那么我们就可以all-in-one 了就类似普通的数据库了,以上是一个简单介绍说明下
dremio dbt 实现上的一些细节,方便学习使用,当然官方也有一个简单的使用介绍可以参考
参考资料
https://github.com/dremio/dbt-dremio
https://www.dremio.com/blog/using-dbt-to-manage-your-dremio-semantic-layer/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2023-04-19 基于cups 协议实现一个灵活的无线打印
2020-04-19 一种基于特性开关以及规则的软件开发模式
2020-04-19 ff4j spring boot 基本试用
2020-04-19 easy-flows 一个简单的工作流引擎
2020-04-19 easy-batch相关qa
2020-04-19 easy-batch job listeners
2020-04-19 easy-batch job validators