发布于 2026-01-06 6 阅读
0

数据工程入门——真正的初学者指南

数据工程入门——真正的初学者指南

这是你在谷歌上搜索数据工程主题,点击“感觉不错”后跳转到的页面,就能找到的关于数据工程的文章。

此外,本文是一位经验丰富的网页开发工程师的个人观点,探讨的是他职业生涯中的一个新课题。也就是说,这是我的研究成果,如果您有任何补充,欢迎在下方评论区留言指点!我非常乐意学习更多!

目录

1. 序言

我必须承认:以前每当有人提到数据工程,我都会走神。它听起来总是那么复杂难懂——简直像魔法一样。

这周,我终于决定深入研究一下。我原以为会很简单,但很快就意识到这其中的门道有多深。

这个领域不仅仅是一些脚本或 SQL 查询;它是一个由相互关联的工具、概念和职责组成的完整生态系统,构成了现代数据系统的支柱。

例如:

  • 数据目录和治理:了解谁拥有数据、如何确保质量以及如何跟踪血缘关系。
  • 编排:使用Apache AirflowDagster等工具协调依赖关系和工作流
  • 转换(ETL/ELT):使用dbtFivetran等工具清理和标准化数据
  • 摄取和流式传输:使用KafkaAirbyteConfluent Cloud连接数据源并实时移动数据
  • 可观测性和质量:使用Monte CarloDatafold等解决方案监控数据健康状况

每点击一篇文章,就仿佛打开了一个全新的工具、词汇、框架、架构和最佳实践的世界。
而所有这些,都必须协同运作——治理、编排、转换、摄取、可观测性、基础设施。

作为一名开发人员,我习惯于学习一门语言和一个框架,然后就开始工作。
但在数据工程领域,情况就不同了。

这关乎理解整个生态系统以及每个部分如何与下一个部分相连。

经过数小时阅读文档、查找 GitHub 代码库、在各种工具、文章和无尽的定义之间切换,我终于找到了让一切都豁然开朗的工具——Bruin

想象一个单一的框架:

  • 管道即代码——所有内容都以版本控制的文本形式(YAML、SQL、Python)存在。没有隐藏的用户界面或数据库。可复现、可审查、可自动化。
  • 天然的多语言支持——原生支持 SQL 和 Python,并且能够插入二进制文件或容器以应对更复杂的用例。
  • 可组合管道——在一个无缝流程中组合技术、源和目标——无需粘合代码,无需技巧。
  • 无厂商锁定——100% 开源(Apache 许可)的命令行界面 (CLI),可在任何地方运行:本地、持续集成 (CI) 环境或生产环境。您可以完全掌控您的流水线和数据。
  • 专为开发者和数据质量而设计——快速本地运行、集成检查和快速反馈循环。经过测试、值得信赖且易于交付的数据产品。

……而且它符合我刚才提到的所有核心数据工程概念。

我承认——我属于那种乐于享受高效“懒惰”的人。如果有一种方法能用更少的工具、更少的阻力完成更多的工作,我肯定会尝试。

那么在开始之前,先来看看计划:

在大多数设置中,数据流从 OLTP 数据库 → 摄取 → 数据湖/仓库 → 转换 → 数据集市 → 分析仪表板。

Airbyte等工具处理数据摄取,dbt处理数据转换,Airflow协调依赖关系——而 Bruin 将这些层合并
到一个统一的框架中。

本文将介绍数据工程的基本原理,并探讨Bruin如何通过一个简单的、真实的管道将它们全部整合在一起。

2. 第一印象:探索布鲁因的结构

说实话,我以前对数据科学/工程项目有点偏见。每次看到这类项目,都感觉杂乱无章,文件和笔记本到处都是。我本身是软件开发人员,这种混乱的局面总是让我很不舒服。

但当我开始研究Bruin 的项目结构时,我的看法彻底改变了。一切都突然变得井然有序、目标明确
这个框架通过其层级结构自然而然地强化了这种结构——一旦你遵循这些层级,一切就都变得合情合理了。

示例:项目结构

├── duckdb.db  
├── ecommerce-mart  
│ ├── assets  
│ │ ├── ingestion  
│ │ │ ├── raw.customers.asset.yml  
│ │ │ ├── raw.order_items.asset.yml  
│ │ │ ├── raw.orders.asset.yml  
│ │ │ ├── raw.products.asset.yml  
│ │ │ └── raw.product_variants.asset.yml  
│ │ ├── mart  
│ │ │ ├── mart.customers-by-age.asset.py  
│ │ │ ├── mart.customers-by-country.asset.yml  
│ │ │ ├── mart.product_performance.sql  
│ │ │ ├── mart.sales_daily.sql  
│ │ │ └── mart.variant_profitability.sql  
│ │ └── staging  
│ │ ├── stg.customers.asset.yml  
│ │ ├── stg.order_items.sql  
│ │ ├── stg.orders.sql  
│ │ ├── stg.products.sql  
│ │ └── stg.product_variants.sql  
│ └── pipeline.yml  
├── glossary.yml  
├── policy.yml  
└── .bruin.yml
Enter fullscreen mode Exit fullscreen mode

各部分的功能

  • .bruin.yml
    • Bruin 环境的主要配置文件。
    • 定义所有管道的全局设置,例如默认连接、变量和行为。
  • policy.yml
    • 您的数据治理和验证策略文件。
    • 定义数据质量规则、访问控制和合规性检查,Bruin 可以在交付数据产品之前自动执行这些规则和检查。
  • glossary.yml
    • 可作为您项目的轻量级数据目录。
    • 记录术语、指标和数据集,以便团队中的每个人都能使用相同的语言。
    • 也有助于血缘关系、文档记录和数据发现。
  • some-feature/pipeline.yml
    • 为某个领域或项目(在本例中为电子商务)定义特定的管道
    • 描述端到端数据流—​​—要运行哪些资产、它们的依赖关系和计划。
    • 管道是模块化的,因此您可以为不同的业务领域维护单独的管道。
  • some-feature/assets/*
    • 包含所有资产——构成数据管道的基本要素。
    • 每个资产都处理一项不同的任务:摄取原始数据、转换数据或生成分析表。
    • 由于每个资源都是一个文件,因此它像代码一样,可以进行版本控制、测试和重用。

仅凭这些,我们就能运行完整的流程。不过,我仍然认为我们需要逐个步骤和文件进行检查——我保证很快就能完成!

2.1.核心文件:.bruin.yml

可以把它看作.bruin.yml项目的根配置——这个文件告诉 Bruin如何以及在哪里运行所有内容。

Bruin 没有将设置分散在脚本或环境变量中,而是将它们集中在此处:连接、凭据和特定于环境的配置都位于同一位置。
它还充当 Bruin 的默认密钥后端,因此您的管道可以安全一致地访问数据库或数据仓库。

bruin run ecommerce/pipeline.yml --config-file /path/to/.bruin.yml
Enter fullscreen mode Exit fullscreen mode

一个简单的例子:

default_environment: default

environments:
  default:
    connections:
      postgres:
        - name: pg-default
          username: postgres # (hardcoded as well)
          password: ${PG_PASSWORD}
          host: ${PG_HOST}
          port: ${PG_PORT}
          database: ${PG_DATABASE}

      duckdb:
        - name: duckdb-default
          path: duckdb.db
Enter fullscreen mode Exit fullscreen mode

这里发生了什么?

  • default_environment— 设置 Bruin 将使用的环境,除非另有指定。
  • environments— 定义多个设置(例如,开发环境测试环境生产环境),每个设置都有自己的配置。
  • connections— 列出 Bruin 可以连接的所有系统,例如 Postgres 或 DuckDB。每个连接都会获得一个名称(例如pg-default),您将在管道和资产中引用该名称。
  • 支持环境变量——任何用 `<value>` 包裹的值${...}都会自动从您的系统环境中读取。

这意味着您可以在本地运行或在 CI/CD 环境中运行的同时,将凭据排除在源代码控制之外。

这种设计使所有内容集中化、安全且版本可控,同时允许您通过环境变量动态注入密钥——非常适合在本地、暂存区和生产区之间切换,而无需修改代码。

2.2. Pipeline:更简单的 Apache Airflow

每个功能都需要一个单独的pipeline.yml文件。
这个文件会将所有资源分组,并识别出运行的不是单个资源,而是一个资源链式列表。

- ecommerce-mart/
  ├─ pipeline.yml -> you're here
  └─ assets/
    ├─ some-asset.sql
    ├─ definitely-an-asset.yml
    └─ another-asset.py
Enter fullscreen mode Exit fullscreen mode

您还可以在那里配置要在特定管道上使用的每个连接:

name: product_ecommerce_marts
schedule: daily # relevant for Bruin Cloud deployments

default_connections:
  duckdb: "duckdb-default"
  postgres: "pg-default"
Enter fullscreen mode Exit fullscreen mode

2.3. 资产:数据产品的构建模块

Bruin中的每个数据管道都由资产组成——模块化的、自包含的单元,用于定义特定的操作:摄取、转换或生成数据集。

每个资产都以文件的形式存在于assets/目录下,其文件名同时也是其在管道图中的标识。

如果你还记得开头展示的文件结构,就应该记得我的流程中包含多种类型的资源。这才是最棒的地方,因为你可以用多种语言编写代码,而且仍然保持简洁易懂。以下是一些示例:

类型 描述 文件名(在文件树中)
YAML 用于摄取或元数据密集型资产的声明式配置 raw.customers.asset.yml
SQL 纯粹的转换逻辑——想想DBT风格的模型 stg.orders.sql
Python 自定义逻辑或集成(例如,API、验证或机器学习步骤) mart.sales_daily.asset.py

您可以自由地组织资源,无需遵循任何固定的层级结构。
关键在于,编排是通过依赖关系隐式实现的,而不是通过像 Airflow 这样的外部 DAG 引擎。

每个资产都会声明它所依赖的资产, Bruin 会自动为您构建和执行依赖关系图。

例子:

  1. raw.orders.asset.yml
# raw.orders.asset.yml
name: raw.orders
type: ingestr
description: Ingest OLTP orders from Postgres into the DuckDB raw layer.
parameters:
  source_connection: pg-default
  source_table: "public.orders"
  destination: duckdb
Enter fullscreen mode Exit fullscreen mode
  1. raw.order_items.asset.yml
# raw.order_items.asset.yml
name: raw.order_items
type: ingestr
description: Ingest OLTP order_items from Postgres into the DuckDB raw layer.
depends:
  - raw.orders  # declares a dependency on the 'raw.orders' asset
parameters:
  source_connection: pg-default
  source_table: "public.order_items"
  destination: duckdb
Enter fullscreen mode Exit fullscreen mode

……变成:

graph TD
    raw.orders --> raw.order_items;
Enter fullscreen mode Exit fullscreen mode

通过这种方式链接资源,您可以描述数据操作之间的逻辑关系,而无需手动编排步骤。
最终形成一个声明式、可组合且易于维护的管道——就像应用程序代码一样,易于阅读、版本控制和扩展。

Bruin 最强大的功能之一在于它将数据质量治理直接集成到您的资产中。
通过为每一列定义检查,您不仅可以验证数据,还可以记录所有权、预期结果和约束条件——所有这些都受到版本控制,并在运行时强制执行。

这意味着 Bruin 不仅运行管道,而且还在同一工作流程中对管道进行审计记录管理。

2.4. 政策:质量与治理的执行

Bruin中的策略就像规则手册,确保数据管道的一致性、合规性和高质量。
它们保证每个资产和管道都遵循最佳实践——从命名规范和所有权到验证和元数据完整性。

策略的核心在于定义在policy.yml项目根目录下的一个文件中。
该文件允许你在流水线运行之前自动进行代码检查验证强制执行标准。

快速概览

rulesets:
  - name: standard
    selector:
      - path: .*/ecommerce/.*
    rules:
      - asset-has-owner
      - asset-name-is-lowercase
      - asset-has-description
Enter fullscreen mode Exit fullscreen mode

每个规则集定义:

  • 规则适用范围selector( →按路径、标签或名称匹配),
  • 要强制执行哪些规则(rules→ 内置或自定义验证规则)。

定义完成后,即可验证整个项目:

bruin validate ecommerce

# Validating pipelines in 'ecommerce' for 'default' environment...
# Pipeline: ecommerce_pg_to_duckdb (.)
#   raw.order_items (assets/ingestion/raw.order_items.asset.yml)
#     └── Asset must have an owner (policy:standard:asset-has-owner)
Enter fullscreen mode Exit fullscreen mode

Bruin 会在执行前自动检查资产——确保不合规的管道永远不会运行

内置规则和自定义规则

规则 目标 描述
asset-has-owner 资产 每项资产都必须明确所有者。
asset-has-description 资产 资产必须包含描述。
asset-name-is-lowercase 资产 资产名称必须全部小写。
pipeline-has-retries 管道 管道必须定义重试设置。

您还可以自定义规则:

custom_rules:
  - name: asset-has-owner
    description: every asset should have an owner
    criteria: asset.Owner != ""
Enter fullscreen mode Exit fullscreen mode

规则可以针对资产管道,并且使用逻辑表达式来确定合规性。

策略将 Bruin 转变为一个自主管理的数据平台——在这个平台上,最佳实践不再是可选项,而是强制执行的。
通过将规则提交到版本控制系统,您可以将数据治理融入开发工作流程,而不是事后才考虑。

2.5 词汇表:使用同一种语言

在数据项目中,最棘手的问题之一并非技术问题,而是沟通
不同的团队常常对同一个词有不同的理解。
这时,布鲁因术语表就派上了用场。

术语表定义在glossary.yml项目的根目录下。
它充当业务概念(例如客户订单)及其属性的共享词典,使各个团队在各个流程中保持一致。

entities:
  Customer:
    description: A registered user or business in our platform.
    attributes:
      ID:
        type: integer
        description: Unique customer identifier.
Enter fullscreen mode Exit fullscreen mode

您可以使用以下方式在资产中引用这些定义extends,从而避免重复并确保一致性:

# raw.customers.asset.yml
name: raw.customers
type: ingestr

columns:
  - name: customer_id
    extends: Customer.ID
Enter fullscreen mode Exit fullscreen mode

这会自动继承词汇表中的` typeand`属性。 这是一个简单却强大的概念——你的数据定义将像代码一样进行版本控制和共享。description

3. 建设我们的第一条管道

既然我们已经了解了Bruin 的结构和理念,现在是时候构建一个端到端的管道了。

我们将从原始数据摄取开始,构建一个干净的暂存层,最终生成可用于分析的数据集市——所有这些都将以代码的形式定义。

我们假设您已经拥有:

  • Postgres数据库作为数据源。
  • 使用DuckDB数据库作为分析存储。
  • 已配置两个连接的工作.bruin.yml文件 ### 3.1 步骤 1:从源数据摄取到数据湖

第一步是将数据从 Postgres 迁移到 DuckDB。

这将创建原始层——数据从源数据库复制而来,仅经过最少的转换。

创建导入资源文件:

touch assets/ingestion/raw.customers.asset.yml
Enter fullscreen mode Exit fullscreen mode

然后定义资产:

# assets/ingestion/raw.customers.asset.yml
name: raw.customers
type: ingestr

description: Ingest OLTP customers from Postgres into the DuckDB raw layer.

parameters:
  source_connection: pg-default
  source_table: "public.customers"
  destination: duckdb

columns:
  - name: id
    type: integer
    primary_key: true
    checks:
      - name: not_null
      - name: unique

  - name: email
    type: string
    checks:
      - name: not_null
      - name: unique

  - name: country
    type: string
    checks:
      - name: not_null
Enter fullscreen mode Exit fullscreen mode

这告诉 Bruin 从你的 Postgres 表中提取数据public.customers,验证列质量,并将其存储在 DuckDB 原始层中。


运行资产

bruin run ecommerce/assets/ingestion/raw.customers.asset.yml 
Enter fullscreen mode Exit fullscreen mode

预期输出:

Analyzed the pipeline 'ecommerce_pg_to_duckdb' with 13 assets.
Running only the asset 'raw.customers'

  Pipeline: ecommerce_pg_to_duckdb (../../..)
  No issues found                                                                                                                                                                                                                                  
✓ Successfully validated 13 assets across 1 pipeline, all good.                                                                                                 
  Interval: 2025-10-12T00:00:00Z - 2025-10-12T23:59:59Z

Starting the pipeline execution...
  PASS raw.customers ........

  bruin run completed successfully in 2.095s

✓ Assets executed      1 succeeded

Enter fullscreen mode Exit fullscreen mode

您现在可以查询已摄取的数据:

bruin query --connection duckdb-default --query "SELECT * FROM raw.customers LIMIT 5"
Enter fullscreen mode Exit fullscreen mode

结果:

┌────┬───────────────────┬───────────────────────────┬───────────┬──────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐
│ ID │ FULL_NAME         │ EMAIL                     │ COUNTRY   │ CITY             │ CREATED_AT                           │ UPDATED_AT                           │
├────┼───────────────────┼───────────────────────────┼───────────┼──────────────────┼──────────────────────────────────────┼──────────────────────────────────────┤
│ 1  │ Allison Hill      │ donaldgarcia@example.net  │ Uganda    │ New Roberttown   │ 2025-10-10 18:19:13.083281 +0000 UTC │ 2025-10-10 00:42:59.71112 +0000 UTC  │
│ 2  │ David Guzman      │ jennifermiles@example.com │ Cyprus    │ Lawrencetown     │ 2025-10-10 07:52:47.643619 +0000 UTC │ 2025-10-10 06:23:42.864287 +0000 UTC │
│ 3  │ Caitlin Henderson │ eric51@example.org        │ Hong Kong │ West Melanieview │ 2025-10-10 21:06:02.639412 +0000 UTC │ 2025-10-10 19:23:17.540169 +0000 UTC │
│ 4  │ Monica Herrera    │ smiller@example.net       │ Niger     │ Barbaraland      │ 2025-10-11 01:33:43.032929 +0000 UTC │ 2025-10-10 02:29:27.22515 +0000 UTC  │
│ 5  │ Darren Roberts    │ wyattmichelle@example.com │ Fiji      │ Reidstad         │ 2025-10-10 12:05:18.734246 +0000 UTC │ 2025-10-10 00:51:13.406526 +0000 UTC │
└────┴───────────────────┴───────────────────────────┴───────────┴──────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

您的原始图层现已建立并验证。


3.2 步骤 2:数据格式化和验证(暂存层)

接下来,我们将对导入的数据进行清洗和标准化处理,然后再用于分析。

这一层称为暂存层 (stg),用于强制执行模式、列一致性并应用业务规则。

创建文件:

touch ecommerce/assets/staging/stg.customers.asset.sql
Enter fullscreen mode Exit fullscreen mode

并将其定义如下:

/* @bruin
name: stg.customers
type: duckdb.sql
materialization:
  type: table

depends:
  - raw.customers

checks:
  columns:
    id:
      - not_null
    email:
      - not_null
      - unique
    country:
      - not_null
@bruin */

SELECT id::INT AS customer_id,
       COALESCE(TRIM(email), '') AS email,
       COALESCE(TRIM(country), 'Unknown') AS country,
       created_at,
       updated_at
FROM raw.customers
WHERE email IS NOT NULL;

Enter fullscreen mode Exit fullscreen mode

事情经过是这样的:

  • Bruin注释块(@bruin定义了资产的元数据。
  • depends关键确保此暂存步骤仅在完成后运行 raw.customers——Bruin 会自动管理依赖链。
  • 检查可确保转换前后的数据质量。
  • SQL 查询本身执行轻量级清理并强制执行类型一致性。

这种设计模仿了Airflow等编排工具,但没有外部调度器——依赖项和检查直接在你的代码中声明。

验证与执行

运行前,请验证资产:

bruin validate ecommerce/assets/staging/stg.customers.asset.sql
Enter fullscreen mode Exit fullscreen mode

预期输出:

Pipeline: ecommerce_pg_to_duckdb (.)
  No issues found      

✓ Successfully validated 13 assets across 1 pipeline, all good.     
Enter fullscreen mode Exit fullscreen mode

现在执行它:

bruin run ecommerce/assets/staging/stg.customers.asset.sql
Enter fullscreen mode Exit fullscreen mode

结果:

bruin run ecommerce/assets/staging/stg.customers.asset.sql
Analyzed the pipeline 'ecommerce_pg_to_duckdb' with 15 assets.
Running only the asset 'stg.customers'

Pipeline: ecommerce_pg_to_duckdb (../../..)
  No issues found                                                                                                                                                                                                                                   

✓ Successfully validated 15 assets across 1 pipeline, all good.                                                       

Interval: 2025-10-12T00:00:00Z - 2025-10-12T23:59:59Z

Starting the pipeline execution...

[21:28:16] Running:  stg.customers
[21:28:16] Finished: stg.customers (41ms)

==================================================

PASS stg.customers 


bruin run completed successfully in 41ms

 ✓ Assets executed      1 succeeded
Enter fullscreen mode Exit fullscreen mode

确认转换是否成功:

bruin query "SELECT country, COUNT(*) AS customers FROM stg.customers GROUP BY country ORDER BY customers DESC;"
Enter fullscreen mode Exit fullscreen mode

示例输出:

country      | customers
--------------+-----------
BRAZIL        | 420
GERMANY       | 255
UNITED STATES | 198
ARGENTINA     | 190
SOUTH KOREA   | 182
Enter fullscreen mode Exit fullscreen mode

至此,您已拥有一个干净、经过验证的数据集,可以进行分析了。

3.3 步骤 3:设计分析(市场)层

最后一步是构建数据市场层,用于存放业务就绪数据。

分析师和仪表盘可以直接查询这一层。

每个数据市场资产都会将暂存数据聚合或重塑为有意义的数据集,以便进行报告和分析。

3.3.1 资产:mart.customers_by_country.asset.sql

创建以下文件:

touch ecommerce/assets/mart/mart.customers_by_country.asset.sql
Enter fullscreen mode Exit fullscreen mode

然后定义资产:

/* @bruin
name: mart.customers_by_country
type: duckdb.sql

materialization:
  type: table

depends:
  - stg.customers
@bruin */

SELECT
    country,
    COUNT(*) AS total_customers
FROM stg.customers
GROUP BY country
ORDER BY total_customers DESC;
Enter fullscreen mode Exit fullscreen mode

此 SQL 资产按国家/地区汇总客户信息,并依赖于stg.customers确保暂存层首先运行的机制。

它在 DuckDB 中以表的形式呈现。

运行它:

bruin run ecommerce/assets/mart/mart.customers_by_country.asset.sql
Enter fullscreen mode Exit fullscreen mode

预期输出:

Pipeline: ecommerce_pg_to_duckdb (.)
Running mart.customers_by_country
✓ Table materialized successfully in DuckDB
Enter fullscreen mode Exit fullscreen mode

验证结果:

bruin query --connection duckdb-default --query "SELECT * FROM mart.customers_by_country LIMIT 5;"
Enter fullscreen mode Exit fullscreen mode

结果:

┌───────────────┬───────────────────┐
│ COUNTRY       │ TOTAL_CUSTOMERS   │
├───────────────┼───────────────────┤
│ BRAZIL        │ 420               │
│ GERMANY       │ 255               │
│ UNITED STATES │ 198               │
│ ARGENTINA     │ 190               │
│ SOUTH KOREA   │ 182               │
└───────────────┴───────────────────┘
Enter fullscreen mode Exit fullscreen mode

3.3.2 资产:mart.customers_by_age.asset.sql

现在,让我们创建第二个超市,将顾客按年龄段划分。

创建文件:

touch ecommerce/assets/mart/mart.customers_by_age.asset.sql
Enter fullscreen mode Exit fullscreen mode

将其定义如下:

/* @bruin
name: mart.customers_by_age  
type: duckdb.sql  

materialization:  
  type: table  
depends:  
  - stg.customers  

@bruin */  

WITH src AS (
  SELECT 
    CASE  
      WHEN age < 25 THEN '18-24'  
      WHEN age BETWEEN 25 AND 34 THEN '25-34'  
      WHEN age BETWEEN 35 AND 49 THEN '35-49'  
      ELSE '50+'  
    END AS age_group  
  FROM stg.customers
)
SELECT 
  age_group,  
  COUNT(*) AS total_customers  
FROM src  
GROUP BY age_group  
ORDER BY total_customers DESC;
Enter fullscreen mode Exit fullscreen mode

该资产使用简单的CASE表达式计算按年龄段划分的客户分布,并汇总结果。

运行它:

bruin run ecommerce/assets/mart/mart.customers_by_age.asset.sql
Enter fullscreen mode Exit fullscreen mode

预期输出:

bruin run ecommerce/assets/mart/mart.customers_by_age.asset.sql
Analyzed the pipeline 'ecommerce_pg_to_duckdb' with 15 assets.
Running only the asset 'mart.customers_by_age'

Pipeline: ecommerce_pg_to_duckdb (../../..)
  No issues found

✓ Successfully validated 15 assets across 1 pipeline, all good.

Interval: 2025-10-12T00:00:00Z - 2025-10-12T23:59:59Z

Starting the pipeline execution...

[21:10:24] Running:  mart.customers_by_age
[21:10:24] Finished: mart.customers_by_age (39ms)

==================================================

PASS mart.customers_by_age 


bruin run completed successfully in 39ms

 ✓ Assets executed      1 succeeded
Enter fullscreen mode Exit fullscreen mode

确认超市货架上的商品已正确摆放:

bruin query --connection duckdb-default --query "SELECT * FROM mart.customers_by_age;"
Enter fullscreen mode Exit fullscreen mode

结果:

┌─────────────┬───────────────────┐
│ AGE_GROUP   │ TOTAL_CUSTOMERS   │
├─────────────┼───────────────────┤
│ 25-34       │ 460               │
│ 35-49       │ 310               │
│ 18-24       │ 250               │
│ 50+         │ 225               │
└─────────────┴───────────────────┘
Enter fullscreen mode Exit fullscreen mode

4. 完整预览数据流

希望我理解正确的话,开头解释的概念没有变得那么混乱,我们实际上只用 Bruin 和几个查询就实现了这个流程!

我们的示例流程如下所示:

graph TD
    raw.customers --> stg.customers
    stg.customers --> mart.customers_by_country
    stg.customers --> mart.customers_by_age
Enter fullscreen mode Exit fullscreen mode

到此阶段,您已经使用 Bruin 构建了一个完全声明式的端到端数据管道——摄取、暂存和分析——所有这些都受到控制、验证和可重现,而无需任何外部编排层。

5. 功能过强的 VS Code 扩展

VS Code 扩展

我第一次安装Bruin VS Code 扩展时,完全不知道该怎么用。

当时,我对Bruin 的工作原理,甚至对数据工程的概念都一窍不通。

我胡乱点击了几下,看到了一堆 YAML 文件和元数据标记,很快就放弃了。

一周后,在终于了解了生态系统(摄取、暂存、市场和治理)之后,我决定再次打开扩展程序,就在那时,一切都豁然开朗了

它不仅仅是个帮手,它是缺失的那一块

该扩展程序将 Bruin CLI 的声明式功能带入到可视化的、对开发者友好的环境中。

它会自动扫描您的资源、验证配置、直接针对数据库运行查询,甚至可以实时管理您的 YAML 文件。

所有操作都在 VS Code 内部完成——验证、血缘探索、元数据检查和查询预览。

VS Code 扩展详情

最让我印象深刻的是它的流畅性和开放性。这里没有厂商锁定——它是完全开源的。

你可以像开发命令行界面 (CLI) 一样,fork 它、扩展它,或者为社区做出贡献。

简而言之,Bruin VS Code 扩展不仅仅是一个辅助工具,更是工作流程的自然演进。一旦你了解了 Bruin,就会觉得这个工具就像魔法终于被揭开了面纱。

6. 结论

这项研究是我第一次真正尝试理解布鲁因(Bruin)以及数据工程在实践中的实际意义。曾经感觉抽象而复杂的内容,在逐步拆解、实验和串联之后,开始变得清晰起来。

我不能说我已经完全理解了所有东西——远非如此——但我终于明白各个部分是如何衔接起来的:数据摄取、暂存、市场、验证和治理。布鲁因帮助我以一种易于理解而非令人不知所措的方式实践了这些概念。

探索、失败、阅读和重建的过程最终证明是最有价值的部分。虽然还有很多东西需要学习,但这无疑是朝着真正理解数据如何流动、转换和讲述故事(就像这篇文章一样)迈出的坚实的第一步。

GitHub 演示:基于 Bruin 的电子商务流程
Bruin 网站

文章来源:https://dev.to/danielhe4rt/data-engineering-101-a-real-beginners-approach-25a8