第27章 Dagster 社区项目展示(下):dbt、DuckDB 与 Hugging Face
最有趣的 Dagster 项目往往来自社区。本文展示了由社区开发的富有创意的应用程序。我们最喜欢的 Dagster 用例,恰恰是那些我们从未预料到的。
社区里的开发者正利用 Dagster 探索公开数据集、监控基础设施、自动化研究工作流、构建内部工具,并尝试完全新型的数据应用。有些项目技术含量极高,有些则非常小众,但无一例外都体现了使用 Dagster 构建系统的人们的创造力。
本文重点介绍了几个引起我们注意的社区项目,分享其背后的故事、创建者为何选择 Dagster,以及他们的构建体验。
正在用 Dagster 做有趣的项目?我们很乐意听听。
Edwin Weber
LinkedIn | GitHub | 邮箱
简单介绍一下你自己和你的工作
我是 Edwin Weber,一名驻荷兰的独立数据工程师。我坚信元数据驱动的数据工程自动化,并在职业生涯中频繁开发此类“框架”。我主要活跃在数据项目的“后端”,负责从源系统提取数据、数据建模、编写转换逻辑、管理编排以及调优 SQL 查询等。
你最初是如何发现 Dagster 的?
我第一次接触 Dagster 是在阅读 Manning Publications 出版的《DuckDB in Action》一书时。书中将 Dagster 提及为编排数据流水线的工具。
后来我选择使用 dbt 进行数据转换,并了解到 Dagster 与 dbt 有出色的集成能力,包括自动发现依赖关系。这让我的数据编排工具选择变得清晰明了:Dagster。
你正在用 Dagster 构建什么项目?
我需要一个个人项目,实际动手构建一些基于我常听说的工具(通常被称为现代数据栈)的东西。我 Fork 了一个类似我环境的开源项目(https://github.com/bgarcevic/danish-democracy-data),并加入了我的想法。
基本思路是:在预算有限的前提下,仅使用开源工具,以尽可能少的可维护组件构建一个完整的数据工程项目。该项目可用地址为:https://github.com/edwinweber/dbt_duckdb_demo_public
该项目使用的技术栈包括:
- 编排:Dagster
- IDE:Visual Studio Code
- 编程语言:Python
- 数据提取:dlt
- 数据转换:dbt
- 数据存储:DuckDB 和 Delta 表
- 计算:DuckDB
- 可视化:Metabase
- 基础设施:开发环境使用本地 Docker 容器,生产环境使用 Hetzner 云服务器
功能:从公共 API 提取数据,使用 dbt 进行转换,并加载到 DuckDB 和 Delta 表中。数据内容涉及丹麦议会的会议和投票记录。数据流经奖牌架构的各层:
- 青铜层(Bronze):从 API 提取的 JSON 数据,在其上建立 DuckDB 视图
- 白银层(Silver):全量历史化数据,通过基于哈希的 CDC(变更数据捕获)检测生成。以表形式存在于 DuckDB 中,以 Delta 表形式存在于选定的文件存储(本地或 Microsoft Fabric Onelake)中
- 黄金层(Gold):用于分析的维度模型,以视图形式存在于 DuckDB 中,以 Delta 表形式存在于选定的文件存储(本地或 Microsoft Fabric Onelake)中
在可视化方面,我使用 Metabase 连接到 DuckDB 实例,以便创建仪表盘并探索议会数据,同时也探索 Dagster 的数据(即存储运行、资产、物化等元数据的 SQLite 数据库)。
你解决的最难或最有意思的问题是什么?
当项目中 dbt 部分运行时,我不得不停止 Metabase 容器,以避免 DuckDB 中的锁冲突。
解决方案是创建两个 Dagster 资产:一个用于停止 Metabase 容器,另一个在 dbt 部分完成后重新启动容器,并将这些“资产”自动添加到每个 Dagster 作业中。资产是非常通用的概念,不仅限于数据流程。
@asset( name="stop_metabase_asset", description="在流水线运行前停止 Metabase。" ) def stop_metabase_asset(): subprocess.run(["./stop_metabase_and_wait.sh"], check=True) def build_start_metabase_asset(upstream_asset_keys: Iterable[AssetKey]) -> AssetsDefinition: unique_keys = sorted(set(upstream_asset_keys), key=lambda key: key.to_user_string()) @asset( name="start_metabase_asset", deps=unique_keys, description="在流水线运行后启动 Metabase。" ) def start_metabase_asset(): subprocess.run(["./start_metabase_and_wait.sh"], check=True) return start_metabase_asset
为什么 Dagster 适合这个项目?
Dagster 非常适合我的项目。它是纯 Python 语言编写的,与我的 dbt 项目集成良好,UI 也很实用。我此前完全没有 Dagster 经验,但很快就能上手,且文档非常优秀。
给初学 Dagster 的人什么建议?
阅读文档,跟着教程做,然后开始构建。如果你也使用 dbt,务必利用 dbt 集成,这样就不必重复定义依赖关系。
UI 确实很棒。如果需要在“DevOps”仪表板中展示更多运行时数据,值得使用其底层 SQLite 数据库进行报告。我专门为该目的在 DuckDB 中定义了基于该数据库的视图。
Parag Ekbote
LinkedIn | GitHub | Hugging Face
简单介绍一下你自己和你的工作
我目前处于人工智能与数据科学本科学位的最后一年。在学习之余,我担任 Manning Publications 的技术审稿人以及特邀演讲嘉宾,这让我有机会深入接触技术内容,并紧跟新兴工具和最佳实践。
我的工作大多围绕机器学习、数据工程和 Hugging Face 生态系统。我喜欢构建工具,让开发者和研究人员能更轻松地处理大规模数据。开源是我成长过程中非常重要的一部分,它让我能从经验丰富的贡献者中学习,并构建能对社区产生实际影响的软件。
你最初是如何发现 Dagster 的?
我在处理 Hugging Face Datasets 时第一次发现了 Dagster。当时我在寻找扩大 Hugging Face Hub 上托管数据集的影响力和易用性的方法,并意识到数据编排在提高数据集摄取、转换和监控的可靠性与可重用性方面可以发挥重要作用。
最初吸引我的是 Dagster 强大的开源社区和异常清晰的文档。由于这是我首次使用专用的数据工程和编排工具,详尽的指南和示例让我受益匪浅。随着进一步探索,我发现 Dagster 基于资产的方法与我思考数据集和流水线的方式天然契合。这种契合最终让我从用户转变为贡献者,致力于让 Hugging Face 和 Dagster 的连接更加无缝。
你正在用 Dagster 构建什么项目?
我构建了一个开源 Python 库,将 Dagster 与 Hugging Face Datasets 集成。目标是让用户能轻松从 Hugging Face Hub 加载任意数据集,使用 Dagster 处理,然后将结果数据集推送回 Hub。
实现过程大量依赖 Dagster 的资产系统和装饰器,让用户只需少量样板代码即可定义数据集工作流。我对该库进行了大量迭代,持续测试不同的数据集配置和处理工作流,直到能够按用户预期的方式可靠地处理数据集。在此过程中,我还收到了来自 Dagster 社区成员(包括 Colton Padden)的宝贵反馈,帮助改善了集成的可用性和设计。
你解决的最难或最有意思的问题是什么?
最具挑战性和意思的问题之一是为该库添加流式支持。Hugging Face 数据集可能极其庞大,支持此类工作流要求我仔细考虑数据如何在 Dagster 的执行模型中流动。
为了使其可行,我实现了一个自定义 IO 管理器,能够在符合 Dagster 资产架构的同时正确处理流式数据集。
另一个挑战是元数据管理。Hugging Face 数据集包含有价值的元数据,用户通常希望保留并将其与处理后的数据集一起发布。
因此,我开发了一个模块,自动从公开的数据集信息中提取元数据,同时允许用户定义和附加自定义元数据。这些元数据随后可以与转换后的数据集一起推送回 Hugging Face Hub,从而创建更完整、更可复现的工作流。
为什么 Dagster 适合这个项目?
Dagster 非常适合,主要归功于其基于资产的架构。Hugging Face 数据集天然映射为资产,因此心智模型从一开始就很直观。我不再将流水线视为一系列孤立的任务,而是将数据集建模为一等对象,关注它们在工作流中的演变。
我还欣赏 Dagster 的集成生态系统及其可扩展性理念。许多编排工具要求用户自行管理外部集成,或将集成与核心项目分离维护。而在 Dagster 中,有维护良好的集成生态系统和一个积极支持新连接器和用例的社区。
给初学 Dagster 的人什么建议?
我最大的建议是小处着手,在构建中学习。之后,花时间阅读文档。Dagster 拥有我接触过的最清晰的文档和使用指南,许多常见问题已有实用示例覆盖。不要试图一次性学会所有东西,而是从一个小项目开始,尝试资产,逐步探索更高级的概念。
我也鼓励大家参与社区。我通过 Hugging Face 社区获得了宝贵反馈,显著塑造了该项目。使用 Dagster 构建感觉往往比维护一堆自定义 Python 脚本更高效。
有反馈或问题?在 Slack 或 GitHub 发起讨论。有兴趣与我们共事?查看我们的开放职位。想要更多类似内容?在 LinkedIn 关注我们。