我正在尝试以编程方式使用 dbt,特别是回调。我想从 StatsLine 事件获取数据:
from dbt.cli.main import dbtRunner, dbtRunnerResult
from dbt.events.base_types import EventMsg
cli_args = ['run', '-m', 'my_model']
def callback_get_stats(event: EventMsg):
if event.info.name == 'StatsLine':
print(event.data)
dbt = dbtRunner(callbacks=[callback_get_stats])
res = dbt.invoke(cli_args)
到目前为止,一切顺利:这将打印 StatsLine 事件的数据部分。
问题:如何将其作为对象获取?
一种选择是使用副作用,例如:
callback_dict = dict()
def callback_get_stats(event: EventMsg):
if event.info.name == 'StatsLine':
print(event.data)
callback_dict['StatsLine'] = event.data
这很好,但看起来不太优雅。我当然可以在函数中添加一个返回...
def callback_get_stats(event: EventMsg):
if event.info.name == 'StatsLine':
print(event.data)
return event.data
...但我不知道它去哪里了!我已经在
dir()
及其子对象上尝试过 res
但我找不到 callback_get_stats
的返回值。
非常有趣的用例。这种场景其实很常见。它与 dbt 并没有太多的联系,甚至与 python 也没有太多的联系。例如,它也可以应用于 javascript。主要和回调的概念有关。
回调旨在在事件发生后执行某些操作。在这种特殊情况下,当
dbtRunner
满足 EventMsg
的标准时,它将调用所有已注册的回调。
主要的困惑在于
return value
。 return value
由回调提供给 dbtRunner
的框架。回调本身根本不使用 return value
。
如果回调本身无法完成实际操作。然后它必须使用一些外部变量,或者一些事件系统。
你提到的有副作用的解决方案是一个很常见的解决方案。