dbt macro 名称获取简单说明
dbt common 包中包含了一个工具模块可以进行macro 的组合
参考代码
可以看出主要是进行组合的,属于一个格式,对于后续任务执行的macro 处理需要使用
from dbt_common.exceptions import DbtInternalError
# dbt 对于macro 会默认包含一个dbt_macro__的前缀
MACRO_PREFIX = "dbt_macro__"
DOCS_PREFIX = "dbt_docs__"
def get_dbt_macro_name(name):
if name is None:
raise DbtInternalError("Got None for a macro name!")
return f"{MACRO_PREFIX}{name}"
def get_dbt_docs_name(name):
if name is None:
raise DbtInternalError("Got None for a doc name!")
return f"{DOCS_PREFIX}{name}"
def get_materialization_macro_name(materialization_name, adapter_type=None, with_prefix=True):
if adapter_type is None:
adapter_type = "default"
name = f"materialization_{materialization_name}_{adapter_type}"
return get_dbt_macro_name(name) if with_prefix else name
def get_docs_macro_name(docs_name, with_prefix=True):
return get_dbt_docs_name(docs_name) if with_prefix else docs_name
def get_test_macro_name(test_name, with_prefix=True):
name = f"test_{test_name}"
return get_dbt_macro_name(name) if with_prefix else name
使用的地方
工具类主要是在common client 的jinja 包装中使用的,包含了dbt 实现的materialization 扩展,macro 解析
- MacroFuzzParser 解析的
class MacroFuzzParser(jinja2.parser.Parser):
def parse_macro(self):
node = jinja2.nodes.Macro(lineno=next(self.stream).lineno)
# modified to fuzz macros defined in the same file. this way
# dbt can understand the stack of macros being called.
# - @cmcarthur
node.name = get_dbt_macro_name(self.parse_assign_target(name_only=True).name)
self.parse_signature(node)
node.body = self.parse_statements(("name:endmacro",), drop_needle=True)
return node
- materialization 扩展的
属于一个自定义tag
class MaterializationExtension(jinja2.ext.Extension):
tags = ["materialization"]
def parse(self, parser):
node = jinja2.nodes.Macro(lineno=next(parser.stream).lineno)
materialization_name = parser.parse_assign_target(name_only=True).name
adapter_name = "default"
node.args = []
node.defaults = []
while parser.stream.skip_if("comma"):
target = parser.parse_assign_target(name_only=True)
if target.name == "default":
pass
elif target.name == "adapter":
parser.stream.expect("assign")
value = parser.parse_expression()
adapter_name = value.value
elif target.name == "supported_languages":
target.set_ctx("param")
node.args.append(target)
parser.stream.expect("assign")
languages = parser.parse_expression()
node.defaults.append(languages)
else:
raise MaterializationArgError(materialization_name, target.name)
if SUPPORTED_LANG_ARG not in node.args:
node.args.append(SUPPORTED_LANG_ARG)
node.defaults.append(jinja2.nodes.List([jinja2.nodes.Const("sql")]))
# 生成materialization macro 名称
node.name = get_materialization_macro_name(materialization_name, adapter_name)
node.body = parser.parse_statements(("name:endmaterialization",), drop_needle=True)
return node
参考生成元数据macro 格式
默认会构建manifest 里边会对于项目使用到的macro 进行汇总,以及元数据信息记录
"macro.dbt_utils.get_table_types_sql": {
"name": "get_table_types_sql",
"resource_type": "macro",
"package_name": "dbt_utils",
"path": "macros/sql/get_table_types_sql.sql",
"original_file_path": "macros/sql/get_table_types_sql.sql",
"unique_id": "macro.dbt_utils.get_table_types_sql",
"macro_sql": "{%- macro get_table_types_sql() -%}\n {{ return(adapter.dispatch('get_table_types_sql', 'dbt_utils')()) }}\n{%- endmacro -%}\n\n",
"depends_on": {
"macros": ["macro.dbt_utils.default__get_table_types_sql"]
},
"description": "",
"meta": {},
"docs": { "show": true, "node_color": null },
"patch_path": null,
"arguments": [],
"created_at": 1710727944.957269,
"supported_languages": null
}
说明
以上是关于dbt 在处理处理macro 名称上的一些说明,这个只是一个约定,实际处理是在manifest 中还会处理的通过的ManifestLoader
后边会介绍下
参考资料
dbt_common/utils/jinja.py(common)
dbt_common/clients/jinja.py (common)
core/dbt/parser/macros.py (core )
core/dbt/clients/jinja_static.py (core)
浙公网安备 33010602011771号