mcpField
R
refactoring-dbt-models

refactoring-dbt-models

github.com/altimateai数据与数据库13035 次安装1 天前更新
代码仓库

关于 refactoring-dbt-models

用于通过小步验证来重构 dbt 模型的技能。它帮助数据开发者追踪下游依赖、保持输出不变,并更新相关文档和测试。

主要功能

  1. 01追踪下游依赖
  2. 02检查下游列的使用情况
  3. 03拆分 CTE 或重复逻辑
  4. 04编译并构建模型依赖链
  5. 05变更后比较输出

适用场景

  1. 01拆分冗长的 dbt 模型
  2. 02将重复逻辑提取为宏
  3. 03更改模型列前评估影响

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/altimateai/data-engineering-skills --skill refactoring-dbt-models

安装后在 Claude Code 中输入/refactoring-dbt-models确认已加载。

详细介绍

dbt 重构

更改前查找所有下游依赖。分小步重构。每次更改后验证输出。

工作流

1. 分析当前模型
cat models/<path>/<model_name>.sql

识别重构机会:

  • 超过 50 行的 CTE → 提取到中间模型
  • 多个模型中重复的逻辑 → 提取为宏
  • 多个连续的联接 → 拆分为多个步骤
  • 复杂的 WHERE 子句 → 提取为暂存筛选条件
2. 查找所有下游依赖

至关重要:了解影响范围后才能进行重构。

# Get full dependency tree (model and all its children)
dbt ls --select model_name+ --output list

# Find all models referencing this one
grep -r "ref('model_name')" models/ --include="*.sql"

向用户报告:“找到 X 个下游模型:[列表]。这些模型会受到更改影响。”

3. 检查下游模型使用了哪些列

更改任何列之前,先检查下游模型引用了哪些列:

# For each downstream model, check what columns it uses
cat models/<path>/<downstream_model>.sql | grep -E "model_name\.\w+|alias\.\w+"

如果下游模型引用了特定列,重构后必须确保这些列仍然可用。

4. 制定重构策略
机会策略
较长的 CTE提取到中间模型
重复的逻辑在 macros/ 中创建宏
复杂的联接拆分为多个中间模型
涉及多个关注点拆分为职责明确的模型
5. 执行重构
模式:将 CTE 提取到模型

之前:

-- orders.sql (200 lines)
with customer_metrics as (
    -- 50 lines of complex logic
),
order_enriched as (
    select ...
    from orders
    join customer_metrics on ...
)
select * from order_enriched

之后:

-- customer_metrics.sql (new file)
select
    customer_id,
    -- complex logic here
from {{ ref('customers') }}

-- orders.sql (simplified)
with order_enriched as (
    select ...
    from {{ ref('raw_orders') }} orders
    join {{ ref('customer_metrics') }} cm on ...
)
select * from order_enriched
模式:提取为宏

之前(在多个模型中重复):

case
    when amount < 0 then 'refund'
    when amount = 0 then 'zero'
    else 'positive'
end as amount_category

之后:

-- macros/categorize_amount.sql
{% macro categorize_amount(column_name) %}
case
    when {{ column_name }} < 0 then 'refund'
    when {{ column_name }} = 0 then 'zero'
    else 'positive'
end
{% endmacro %}

-- In models:
{{ categorize_amount('amount') }} as amount_category
6. 验证更改
# Compile to check syntax
dbt compile --select +model_name+

# Build entire lineage
dbt build --select +model_name+

# Check row counts (manual)
# Before: Record expected counts
# After: Verify counts match
7. 验证输出与原始输出一致

至关重要:重构不应改变输出。

# Compare row counts before and after
dbt show --inline "select count(*) from {{ ref('model_name') }}"

# Spot check key values
dbt show --select <model_name> --limit 10
8. 更新下游模型

如果更改了输出列:

  1. 更新所有下游引用
  2. 更新 schema.yml 文档
  3. 重新运行下游测试

重构检查清单

  • 已识别所有下游依赖
  • 已告知用户影响范围
  • 一次只做一项更改
  • 每次更改后编译通过
  • 每次更改后构建通过
  • 已验证输出(行数一致)
  • 已更新文档
  • 测试仍然通过

常见重构触发因素

症状重构方式
模型超过 200 行将 CTE 提取到模型中
3 个或更多模型中有相同逻辑提取为宏
一个模型中有 5 个或更多联接创建中间模型
难以理解添加名称清晰的 CTE
性能缓慢拆分以支持并行处理

反模式

  • 重构前未检查下游影响
  • 一次进行多项更改
  • 重构后未验证输出是否一致
  • 过早提取(等待至少 3 处使用)
  • 未更新测试就破坏现有测试

评论

支持 Markdown