首页 > 其他分享 >dbt return macro 内部实现简单说明

dbt return macro 内部实现简单说明

时间:2024-03-26 15:38:16浏览次数:16  
标签:return macro self context data dbt

jinja2 默认是没有return macro 的,dbt 在实现的时候比较有意思,通过一个exception 触发的,以下是简单说明

参考使用

  • 一个包含return 的macro
{% macro demoapp(name,version) %}
   {%  if version =='v1' %}
       {{return("appdemo") }}
    {% else %}
        {{return("dalongdemo")}}
    {% endif %}
    {{name }} --  {{version}}
{% endmacro  %}
  • 简单说明
    以上如果version 为v1 会返回appdemo ,否则为dalongdemo,后边部分是不会执行的,一个使用生成效果
{{ config(materialized='table') }}
 
select * from  {{demoapp('dalong','v1')}}

编译sql

dbt 内部实现简单说明

实际上return 为dbt 通过context 传递为jinja2 模版引擎的,return 实现是一个exception,这样执行就异常了,但是dbt 自己处理了异常

  • context 变量定义
@contextmember("return")
    @staticmethod
    def _return(data: Any) -> NoReturn:
        """The `return` function can be used in macros to return data to the
        caller. The type of the data (`dict`, `list`, `int`, etc) will be
        preserved through the return call.
 
        :param data: The data to return to the caller
   
        > macros/example.sql:
 
            {% macro get_data() %}
              {{ return([1,2,3]) }}
            {% endmacro %}
 
        > models/my_model.sql:
 
            select
              -- getdata() returns a list!
              {% for i in getdata() %}
                {{ i }}
                {% if not loop.last %},{% endif %}
              {% endfor %}
 
        """
        raise MacroReturn(data)
  • MacroReturn 实现
class MacroReturn(DbtBaseException):
    """This is how we return a value from a macro, not an exception.
 
    Hack of all hacks
    """
 
    def __init__(self, value) -> None:
        self.value = value
  • 调用部分
    dbt_common/clients/jinja.py BaseMacroGenerator 类
def call_macro(self, *args, **kwargs):
    # called from __call__ methods
    if self.context is None:
        raise DbtInternalError("Context is still None in call_macro!")
    assert self.context is not None
 
    macro = self.get_macro()
 
    with self.exception_handler():
        try:
            return macro(*args, **kwargs)
        except MacroReturn as e:
            return e.value

说明

dbt 对于renturn macro 的实现比较有意思,实际上是通过raise exception 实现的,这样jinja2的模版就具有了特定条件返回执行的能力了

参考资料

dbt_common/clients/jinja.py
dbt_common/exceptions/macros.py
core/dbt/context/base.py

标签:return,macro,self,context,data,dbt
From: https://www.cnblogs.com/rongfengliang/p/18093829

相关文章

  • jinja2 通过Template. make_module 进行动态macro 创建以及macro 方法调用
    实际属于一个小技巧,可以实现比较灵活的jinja2扩展,是从dbt对于macro的处理部分学习到的参考代码app.pyfromjinja2importEnvironment env=Environment() #定义macro的内容macro_template="""{%macromydemo(name,age)-%}{{name......
  • 从零开始的 dbt 入门教程 (dbt cloud 自动化篇)
    一、引在前面的几篇文章中,我们从dbtcore聊到了dbt项目工程化,我相信前几篇文章足够各位数据开发师从零快速入门dbt开发,那么到现在我们更迫切需要解决的是如何让数据更新做到定时化,毕竟作为开发我们肯定没有经历每天定点去手动运行dbt命令,那么今天我们将带领大家快速上手......
  • dfs的return时机问题
    题目链接错误代码的\(dfs\)方式:voiddfs(intu,intcnt){if(u==n)return;if(n-u+cnt<m)return;if(cnt==m)//再往下dfs没有意义了,剪枝{dp();return;}dfs(u+1,cnt);del[u]=tru......
  • Using the TRACE_EVENT() macro (Part 1)
    如果你对tracepoint后面的机制感兴趣,可以阅读关于TRACE_EVENT的三篇文章。这一系列文章对tracepoint后面的机制进行了详细讲解,以及其使用方法都有涉及。该系列文章出现在lwn.net上。注意,不要被英文吓住了,我保证,你认真读完这系列文章后,tracepoint后面的秘密不在是秘密。Using......
  • [Rust] Using Box<dyn error::Error>> return one of miultiple error types at runti
    usestd::error;usestd::fmt;usestd::num::ParseIntError;fnmain()->Result<(),Box<dynerror::Error>>{letpretend_user_input="42";letx:i64=pretend_user_input.parse()?;println!("output={:?}",Po......
  • 从__builtin_eh_return看callee saved register
    问题C++的异常处理看起来是一个比较神奇的功能,能够在运行时穿越堆栈,从异常发生位置直达异常处理位置。通过gcc的代码可以看到,这个堆栈回溯的一个关键步骤是这个宏,其中又使用了gcc的内置指令__builtin_eh_return。网上关于__builtin_eh_return这个内置函数的资料较少,结合gcc的源代......
  • JAVA基础:引用类型参数传递的相关案例(数组的传递) 方法重载 return关键字
    packagecom.itheima.Method;publicclassMethod6{publicstaticvoidmain(String[]args){int[]arrs=newint[]{2,5,6,4};printArray(arrs);}publicstaticvoidprintArray(int[]arr){if(arr!=null){System.out......
  • [Rust] Write macro
    Defineamacroanduseit:macro_rules!my_macro{()=>{println!("Checkoutmymacro!");};}fnmain(){my_macro!();} Noticethatyouhavetimedefine macrobeforemainfunction.Otherwiseitdoesn'twork. E......
  • [Rust] Implicitly returning values from functions
    Codehaserror:fnmain(){letanswer=square(3);println!("Thesquareof3is{}",answer);}fnsquare(num:i32)->i32{num*num;}Error:⚠️Compilingofexercises/functions/functions5.rsfailed!Pleasetryagain.Here&#......
  • 协变返回类型(covariant return type)
    协变返回类型(covariantreturntype)C++中的协变返回类型(covariantreturntype)是指派生类(子类)中的虚函数返回类型可以是基类(父类)中虚函数返回类型的子类。这个特性使得在派生类中可以返回更具体的类型,而不违反了虚函数的约定。在C++11中,如果派生类的虚函数覆盖基类的虚函数,并......