例如构建、运行、测试、文档、快照、克隆等。有很多 dbt 命令需要执行,如果你和我一样,你经常在命令历史中查找你所需的命令——只为了省去重新输入整个命令的麻烦。当你经常同时执行多个命令时,尤其如此。一定有更好的解决方法吧?
捕手在BI中的角色(业务智能)
Makefile 救场除非你编译过软件,否则你可能之前没有见过 Makefile。它用来管理编译代码所需的所有依赖关系和命令,但你也可以用它们来在 Linux 或 Mac OS 中自动执行任何任务。
使用 Makefile,你可以创建你自己的抽象命令。你可能会需要它,例如:当你需要简化复杂的构建步骤时,当你希望重复使用某些构建步骤时,当你需要管理多个文件或目录的构建任务时。
- 你经常需要运行相同的命令
- 这些命令很长,你不想输入,也不想在命令历史中查找
- 你希望用
&&
将命令逻辑地组合在一起 - 你希望分享命令,或将常用的命令模式加入到你的项目里
我们不需要深入了解Makefile的细节。最关键的是,我们可以创建包含目标和命令的规则。我们将使用一个特殊的‘伪目标’(稍后会详细介绍),它允许你指定想要运行的命令。
来个简单的例子吧这里有一个简单的 Makefile,可以生成并展示 dbt 文档,如下:
# 生成并运行dbt文档
.PHONY: docs
docs:
dbt docs generate && dbt docs serve
- 在项目的根目录下创建一个名为
Makefile
的文件(不要加文件扩展名),并把上面的那些行放进去。 - 从项目根目录运行
make docs
,你会发现执行了这样的命令dbt docs generate && dbt docs serve
。
$ make docs
dbt docs generate && dbt docs serve
04:35:12 运行中,使用 dbt 版本 1.7.9
04:35:12 注册了 adapter: duckdb 版本 1.7.2
04:35:12 找到了 7 个模型,25 个测试,3 个数据源,0 个暴露,0 个指标,582 个宏,0 个组,0 个语义模型
...
...
.PHONY
你可能注意到了以 .PHONY
开头的那行,这和霍尔登·考菲尔德(来自《麦田里的守望者》中的主人公)没关系,它是一种定义虚拟目标的方法。这些是 makefile 规则,引用的是命令而不是文件。
你只需要记住,为了它们正常工作,你需要将目标标记为‘.Phony’。你可以像上面的简单示例那样,在每个目标上方这样做,或者,你也可以将它们一次性声明,如下所示:
.PHONY: 构建 测试 文档 帮助
这定义了四个伪目标:build、test、docs和help,并将它们放在你的Makefile文件的顶部。
继续在此基础上发展你添加的命令完全取决于你自己的工作流程,而这正是它的美妙之处——这些命令是你具体项目中对你有用的特定命令。
这里有一些基本示例,比如,你可能会添加:
.PHONY: 运行 种子 文档 大杂烩 打扫
运行:
dbt run && dbt test
种子:
dbt seed && dbt run
文档:
dbt docs generate && dbt docs serve
大杂烩:
dbt clean && dbt deps && dbt seed && dbt run && dbt test
打扫:
dbt clean && dbt deps
高级示例
你可以通过在命令行中传递变量给你的 Makefile,甚至还可以加载环境变量来进一步提升你的构建流程。
通过命令行传递变量比如说你想要有一个 dbt 构建命令行,并且能够指定你的 dbt 环境。
.PHONY: build
build:
@echo "环境 $(TARGET) 构建项目" # `@`符号在原Makefile中用于抑制命令的回显,此处保留以保持语义一致性。
环境 $(TARGET) 构建项目
# $(TARGET)表示构建环境,如开发环境或生产环境。
注意:“@”符号在原Makefile中用于抑制命令的回显,此处保留以保持语义一致性。
你可以用 make 命令指定要使用的 dbt 目标环境:
$ make build TARGET=dev
用 dev 环境构建项目
dbt build --target dev
04:11:42 运行中,使用 dbt 版本 1.7.9
当你在makefile中使用环境变量时,你就能发现它如何成为一个非常有用的工具来操作你项目中的文件和构建过程。
设置环境参数要引入你的 .env
环境文件,请在你的 makefile 文件的开头添加以下内容:
source .env
export
你的 Makefile 现在会加载所有的 .env
变量,你可以选择指定默认的 dbt 目标,例如:
目标环境=dev
然后,更新您的 makefile 以检查是否存在 .env
变量。
include .env
export
# 若未设置 TARGET,使用默认值
TARGET ?= $(TARGET)
.PHONY: build
build:
@echo "构建环境为 $(TARGET) 的项目"
dbt build --target $(TARGET)
现在,当你运行命令 make build
时,会使用目标 dev
。但你也可以通过在运行时指定 TARGET
参数来覆盖它。
# 覆盖默认的 .env 文件的目标
make build TARGET=prod
这使得 makefiles 更像是 bash 脚本(Linux 专家可能会因为我说这话而想把我杀了),特别是当你还能加载环境变量时。
帮助中心当你写完所有命令后,添加一个帮助说明来解释你创建的所有命令。这真的让你的工具看起来就像一个自定义的命令行工具一样。
# 显示可用命令
// 定义一个假目标,用于帮助命令
// 帮助命令,输出可用命令列表
@echo "可用的命令:"
@echo "docs - 生成并提供默认目标的文档服务"
一个用于常见 dbt 任务的标准 Makefile 文件
这里有一个你可以用来开始的模板。没有什么特别花哨的,但能帮助你上手。
如果没有的话,请记得创建一个 .env
文件,并在其中设置你项目的默认 TARGET
和 PROFILE
。
看看Alex在他的Zero to dbt项目中的makefile,这可以让你了解实际项目中具有具体的要求和依赖的Makefile是什么样子。
include .env
export
phony: 运行 清理 清理日志 鸭子调试 鸭子生产
DBT_TARGET = dev
运行:
@echo "SPODBTIFY_SOURCE_PARQUET = $SPODBTIFY_SOURCE_PARQUET"
dbt run --target $(DBT_TARGET)
doc:
dbt docs generate && dbt docs serve
鸭子调试:
duckdb spodbtify.duckdb -cmd "USE spodbtify.dev; show all tables"
鸭子生产:
duckdb spodbtify.duckdb -cmd "USE spodbtify.prod; show all tables"
清理:
unset SPODBTIFY_SOURCE_PARQUET && dbt clean && rm -rf *.duckdb
清理日志:
rm -rf logs/*.log
项目使用了duckdb,因此,Alex为此创建了一些目标,以运行duckdb并展示prod和dev环境中的表。你项目中makefile的使用方式将很大程度上取决于你的配置,也就是说,你的makefile的使用会非常依赖于项目的具体设置。
总结。Makefile可以是非常实用的工具来掌控你使用的命令。如果你经常运行一串命令,或者有一些特定于项目的常规任务,它会非常有用。
一个可能的缺点是通过将原始命令抽象化,你会与那些命令疏远。你可能会忘记原来的命令,或者错过一些新功能或使用习惯。因此,定期回顾一下你的构建文件非常有帮助。
你在项目中用Makefile吗?有什么好用的小技巧或有趣的用法吗?请在评论区分享一下。