dbt-core测试框架与质量保障体系

dbt-core测试框架与质量保障体系

【免费下载链接】dbt-core dbt-labs/dbt-core: 是一个基于 Python 语言的数据建模和转换工具,可以方便地实现数据仓库的建模和转换等功能。该项目提供了一个简单易用的数据建模和转换工具,可以方便地实现数据仓库的建模和转换等功能,同时支持多种数据仓库和编程语言。 【免费下载链接】dbt-core 项目地址: https://gitcode.com/GitHub_Trending/db/dbt-core

dbt-core项目构建了完善的单元测试与集成测试体系,采用分层测试架构和金字塔模型确保代码质量和功能稳定性。测试体系包含单元测试层、集成测试层和功能测试层,通过精心设计的测试策略、工具链和丰富的测试组件(如测试工具函数、Mock对象与Fixtures系统),为dbt这一核心数据转换工具提供了可靠的品质保障。测试架构遵循隔离性、可重复性、性能、覆盖性和可维护性等核心设计原则,并集成了完整的测试工具链。

单元测试与集成测试架构

dbt-core项目采用了分层测试架构,构建了完善的单元测试与集成测试体系,确保代码质量和功能稳定性。该测试架构遵循现代软件工程最佳实践,通过精心设计的测试策略和工具链,为dbt这一核心数据转换工具提供了可靠的品质保障。

测试体系整体架构

dbt-core的测试体系采用金字塔模型,从底层的单元测试到顶层的端到端集成测试,形成了完整的质量保障链条:

mermaid

单元测试架构设计

测试目录结构与组织

dbt-core的单元测试位于tests/unit/目录下,按照功能模块进行组织:

tests/unit/
├── cli/                 # CLI命令测试
├── events/              # 事件系统测试
├── materializations/    # 物化策略测试
├── config/              # 配置系统测试
├── graph/               # 图算法测试
├── utils/               # 工具函数测试
├── plugins/             # 插件系统测试
├── parser/              # 解析器测试
├── contracts/           # 合约验证测试
├── clients/             # 客户端测试
├── context/             # 上下文测试
├── deps/                # 依赖管理测试
└── task/                # 任务执行测试
核心测试组件

测试工具函数位于core/dbt/tests/util.py,提供了丰富的测试辅助功能:

def run_dbt(args: Optional[List[str]] = None, expect_pass: bool = True):
    """执行dbt命令并返回结果"""
    # 实现细节...

def get_manifest(project_root) -> Optional[Manifest]:
    """获取解析后的manifest文件"""
    # 实现细节...

def run_dbt_and_capture(args: Optional[List[str]] = None, expect_pass: bool = True):
    """执行dbt命令并捕获输出"""
    # 实现细节...

Mock对象与Fixtures系统提供了灵活的测试数据构造能力:

@pytest.fixture
def basic_parsed_source_definition_object():
    return SourceDefinition(
        columns={},
        database="some_db",
        description="",
        fqn=["test", "source", "my_source", "my_source_table"],
        identifier="my_source_table",
        loader="stitch",
        name="my_source_table",
        # ... 其他属性
    )
典型单元测试示例

以图算法测试为例,展示了dbt-core如何测试复杂的依赖关系解析:

def test_linker_add_dependency(self, linker: Linker) -> None:
    """测试依赖关系添加功能"""
    actual_deps = [("A", "B"), ("A", "C"), ("B", "C")]
    
    for l, r in actual_deps:
        linker.dependency(l, r)
    
    queue = self._get_graph_queue(_mock_manifest("ABC"), linker)
    
    # 验证执行顺序符合依赖关系
    got = queue.get(block=False)
    assert got.unique_id == "C"  # C没有依赖,应该先执行

集成测试架构设计

功能测试组织结构

集成测试位于tests/functional/目录,按功能领域划分:

tests/functional/
├── adapter/              # 适配器特定测试
├── analysis/             # 分析功能测试
├── assertions/           # 断言功能测试
├── cli/                  # CLI集成测试
├── configs/              # 配置集成测试
├── custom_target_path/   # 自定义路径测试
├── cycles/               # 循环依赖测试
├── data_tests/           # 数据测试功能
├── dependencies/         # 依赖管理集成测试
├── deprecations/         # 废弃功能测试
├── docs/                 # 文档生成测试
├── events/               # 事件系统集成测试
└── ...                   # 其他功能模块
测试项目Fixtures系统

dbt-core设计了强大的项目Fixtures系统,支持动态创建测试环境:

@pytest.fixture(scope="class")
def project(
    logs_dir,
    unique_schema,
    project_root,
    profiles_root,
    profiles_yml,
    clean_up_logging,
    dbt_project_yml,
    dependencies_yml,
    packages_yml,
    selectors_yml,
    models,
    macros,
    seeds,
    snapshots,
    tests,
    analyses,
    properties,
):
    """创建完整的dbt测试项目环境"""
    # 创建目录结构
    for dir_name in ["models", "macros", "seeds", "snapshots", "tests", "analyses", "data"]:
        os.makedirs(os.path.join(project_root, dir_name), exist_ok=True)
    
    # 写入模型文件
    for name, content in models.items():
        write_file(content, project_root, "models", name)
    
    # 返回项目信息对象
    return TestProjInfo(
        project_root=project_root,
        profiles_root=profiles_root,
        # ... 其他属性
    )
典型集成测试示例

基础工作流测试验证完整的dbt执行流程:

def test_basic(project):
    """测试基础模型编译和执行流程"""
    # 执行dbt run命令
    results = run_dbt(["run"])
    assert len(results) == 1
    
    # 验证manifest中包含正确节点
    manifest = get_manifest(project.project_root)
    assert "model.test.my_model" in manifest.nodes
    
    # 验证数据库中存在对应表
    relation = relation_from_name(project.adapter, "my_model")
    assert check_table_does_exist(project.adapter, relation)

复杂依赖关系测试验证多模型间的引用关系:

def test_model_dependencies(project):
    """测试模型间依赖关系解析"""
    # 执行完整构建流程
    results = run_dbt(["run"])
    
    # 验证执行顺序符合依赖关系
    execution_order = [r.node.name for r in results]
    assert execution_order.index("stg_customers") < execution_order.index("customers")
    assert execution_order.index("stg_orders") < execution_order.index("orders")
    assert execution_order.index("stg_payments") < execution_order.index("payments")

测试数据管理策略

测试数据生成与维护

dbt-core采用多种策略管理测试数据:

数据类型存储位置管理方式示例
小型测试数据测试文件内嵌字符串变量my_model_sql = "select 1 as fun"
中型测试数据fixtures模块Python字典Jaffle Shop示例数据
大型测试数据data目录CSV文件种子文件和数据文件
动态测试数据运行时生成程序生成随机数据和模式数据
数据驱动测试模式

采用数据驱动测试模式,提高测试覆盖率和可维护性:

@pytest.mark.parametrize("materialized,expected_type", [
    ("table", "BASE TABLE"),
    ("view", "VIEW"),
    ("materialized_view", "MATERIALIZED VIEW"),
    ("ephemeral", None)  # 临时模型不创建数据库对象
])
def test_materialization_types(project, materialized, expected_type):
    """测试不同物化类型的正确性"""
    model_sql = "select 1 as id"
    model_config = {"materialized": materialized}
    
    # 创建测试模型
    write_file(model_sql, project.project_root, "models", "test_model.sql")
    write_file(yaml.safe_dump({"models": [{"name": "test_model", "config": model_config}]}),
              project.project_root, "models", "schema.yml")
    
    # 执行并验证
    run_dbt(["run"])
    if expected_type:  # 非临时模型
        relation = relation_from_name(project.adapter, "test_model")
        actual_type = get_relation_type(project.adapter, relation)
        assert actual_type == expected_type

测试执行与报告体系

测试配置与执行控制

dbt-core使用pytest作为测试框架,配置丰富的执行选项:

# pytest.ini 配置
[pytest]
testpaths = tests/unit tests/functional
addopts = -v --tb=short -x
python_files = test_*.py
python_classes = Test*
python_functions = test_*
测试覆盖率监控

通过codecov集成实现测试覆盖率监控:

# codecov.yml 配置
coverage:
  status:
    project:
      default:
        target: 85%
        threshold: 1%
    patch: off

comment: off

ignore:
  - "tests/"
  - "dbt/adapters/*"

测试架构设计原则

dbt-core的测试架构遵循以下核心设计原则:

  1. 隔离性原则:单元测试完全隔离外部依赖,集成测试控制依赖范围
  2. 可重复性原则:所有测试具备幂等性,可重复执行且结果一致
  3. 性能原则:测试执行高效,单元测试毫秒级,集成测试秒级完成
  4. 覆盖性原则:追求高代码覆盖率,重点覆盖核心业务逻辑
  5. 可维护性原则:测试代码保持简洁清晰,便于理解和维护

测试工具链集成

dbt-core集成了完整的测试工具链:

工具类型工具名称用途集成方式
测试框架pytest测试执行和断言原生支持
覆盖率工具coverage.py代码覆盖率统计pytest插件
mocking库unittest.mock模拟对象创建标准库集成
报告工具pytest-htmlHTML测试报告插件集成
性能监控pytest-benchmark性能基准测试可选集成

这种精心设计的测试架构使得dbt-core能够保持高质量的代码标准,同时支持快速的迭代开发和可靠的功能交付。通过单元测试与集成测试的有机结合,dbt-core为数据工程团队提供了稳定可靠的数据转换基础设施。

功能测试用例设计与实现

dbt-core的功能测试框架采用基于pytest的现代化测试架构,通过精心设计的测试用例结构和丰富的工具函数,确保了数据转换逻辑的准确性和可靠性。功能测试用例的设计遵循模块化、可读性和可维护性原则,为开发者提供了强大的测试能力。

测试用例结构设计

dbt-core的功能测试用例采用分层结构设计,每个测试类都继承自基础测试类,实现了测试逻辑的高度复用。典型的测试用例结构如下:

import pytest
from dbt.tests.util import run_dbt, get_manifest

# 测试数据定义
my_model_sql = """
select 1 as id, 'test' as name
"""

class TestBasicFunctionality:
    @pytest.fixture(scope="class")
    def models(self):
        return {"my_model.sql": my_model_sql}
    
    def test_basic_model_execution(self, project):
        """测试基础模型执行功能"""
        results = run_dbt(["run"])
        assert len(results) == 1
        manifest = get_manifest(project.project_root)
        assert "model.test.my_model" in manifest.nodes

测试夹具系统

dbt-core的测试框架提供了丰富的pytest夹具(fixtures),支持不同范围的测试环境配置:

mermaid

核心夹具功能说明
夹具名称作用域描述
projectclass完整的测试项目环境,包含所有配置
modelsclass模型文件定义,返回文件名到内容的映射
packagesclass依赖包配置
project_config_updateclass项目配置更新
test_data_dirmodule测试数据目录路径

测试工具函数库

dbt-core提供了丰富的测试工具函数,覆盖了各种测试场景:

# 核心测试工具函数示例
from dbt.tests.util import (
    run_dbt,           # 执行dbt命令
    run_dbt_and_capture, # 执行并捕获输出
    get_manifest,      # 获取manifest文件
    get_run_results,   # 获取运行结果
    check_relations_equal, # 检查关系相等性
    write_file,        # 写入文件
    read_file,         # 读取文件
    copy_file          # 复制文件
)
工具函数分类表
类别函数示例用途
命令执行run_dbt, run_dbt_and_capture执行dbt命令并处理结果
文件操作write_file, read_file, copy_file测试文件管理
数据验证check_relations_equal, get_manifest验证数据正确性
配置管理update_config_file, write_config_file动态配置更新

测试用例设计模式

1. 基础功能测试模式
class TestModelFunctionality:
    @pytest.fixture(scope="class")
    def models(self):
        return {
            "model.sql": "select 1 as id",
            "schema.yml": """
                version: 2
                models:
                  - name: model
                    columns:
                      - name: id
                        tests:
                          - unique
            """
        }
    
    def test_model_creation(self, project):
        results = run_dbt(["run"])
        assert len(results) == 1
        assert results[0].status == "success"
    
    def test_model_validation(self, project):
        test_results = run_dbt(["test"])
        assert all(r.status == "pass" for r in test_results)
2. 依赖关系测试模式
class TestDependencyHandling:
    @pytest.fixture(scope="class")
    def models(self):
        return {
            "source_model.sql": "select 1 as source_id",
            "dependent_model.sql": "select source_id from {{ ref('source_model') }}"
        }
    
    def test_ref_functionality(self, project):
        run_dbt(["run"])
        # 验证依赖关系正确解析
        manifest = get_manifest(project.project_root)
        source_node = manifest.nodes["model.test.source_model"]
        dependent_node = manifest.nodes["model.test.dependent_model"]
        
        assert dependent_node.depends_on.nodes == [source_node.unique_id]
3. 错误处理测试模式
class TestErrorHandling:
    @pytest.fixture(scope="class")
    def models(self):
        return {"invalid_model.sql": "select invalid_column from non_existent_table"}
    
    def test_error_handling(self, project):
        with pytest.raises(Exception) as excinfo:
            run_dbt(["run"], expect_pass=False)
        
        assert "invalid_column" in str(excinfo.value)
        assert "non_existent_table" in str(excinfo.value)

高级测试场景实现

数据对比测试
def test_data_integrity(project):
    # 设置测试数据
    project.run_sql("create table expected_data (id integer, name varchar)")
    project.run_sql("insert into expected_data values (1, 'test'), (2, 'example')")
    
    # 运行dbt模型
    run_dbt(["run"])
    
    # 验证数据一致性
    check_relations_equal(
        project.adapter, 
        ["expected_data", "my_model"]
    )
增量模型测试
class TestIncrementalModels:
    @pytest.fixture(scope="class")
    def models(self):
        return {
            "incremental_model.sql": """
                {{ config(materialized='incremental') }}
                select * from {{ ref('source_data') }}
                {% if is_incremental() %}
                where updated_at > (select max(updated_at) from {{ this }})
                {% endif %}
            """
        }
    
    def test_incremental_behavior(self, project):
        # 初始加载
        run_dbt(["run"])
        initial_count = project.run_sql("select count(*) from incremental_model")[0][0]
        
        # 添加新数据后再次运行
        project.run_sql("insert into source_data values (3, 'new', current_timestamp)")
        run_dbt(["run"])
        
        new_count = project.run_sql("select count(*) from incremental_model")[0][0]
        assert new_count == initial_count + 1

测试覆盖率与质量保障

dbt-core的功能测试框架通过以下机制确保测试质量:

  1. 全面性覆盖:每个核心功能都有对应的测试用例
  2. 边界条件测试:包括错误处理、极端情况测试
  3. 性能基准测试:确保代码变更不会导致性能退化
  4. 回归测试:防止已修复的问题再次出现

测试用例的设计遵循ARRANGE-ACT-ASSERT模式,确保测试逻辑清晰明了。通过丰富的断言库和验证工具,开发者可以轻松编写出高质量的功能测试用例,为dbt-core的稳定性和可靠性提供坚实保障。

性能测试与基准测试方法

dbt-core项目构建了一套科学严谨的性能回归测试体系,通过统计学方法和自动化工具链确保代码变更不会引入性能退化。该体系基于统计学显著性检验原理,采用Rust编写的高性能测试运行器,能够准确检测出微小的性能变化。

测试架构设计

dbt-core的性能测试架构采用分层设计,包含测试项目、基准数据、运行器和统计分析四个核心组件:

mermaid

测试项目设计

性能测试使用专门设计的dbt项目来模拟真实世界的性能瓶颈场景。当前主要的测试项目包含2000个简单数据模型,这些模型被组织在分层目录结构中:

-- 示例模型文件内容
SELECT 
    id,
    name,
    created_at,
    updated_at
FROM {{ ref('previous_model') }}
WHERE status = 'active'

每个模型目录包含10个SQL模型文件和对应的YAML配置文件,这种设计能够有效测试dbt的解析、编译和依赖解析性能。

基准测试方法论

dbt-core采用科学的基准测试方法,基于以下核心原则:

  1. 多轮次运行:每个测试场景运行多次(通常20次)以减少随机误差
  2. 统计学建模:计算均值和标准差建立性能基准模型
  3. 显著性检验:使用3σ(西格玛)原则检测性能回归

基准数据存储格式采用JSON结构,包含详细的性能指标:

{
  "command": "dbt parse",
  "mean": 41.22,
  "stddev": 0.2525,
  "min": 40.89,
  "max": 41.98,
  "median": 41.20,
  "user": 40.1,
  "system": 1.12,
  "min_wall": 40.89,
  "max_wall": 41.98
}

统计显著性检测

性能回归检测基于假设检验原理,使用单边3σ检验标准:

σ值p-value显著性水平检测结果
1/6不显著通过
1/44边缘显著警告
1/741显著回归检测
1/31,574高度显著确认回归
1/3,486,914极度显著严重回归

检测公式为:

回归条件: x > μ + 3σ
其中: μ为均值, σ为标准差, x为观测值

Rust性能运行器

测试运行器使用Rust编写,提供两个核心命令:

建模命令:建立新版本的性能基准

./runner model --version 1.4.6 \
              --projects-dir ./performance/projects \
              --baselines-dir ./performance/baselines \
              --n-runs 20

采样命令:检测当前提交的性能回归

./runner sample --projects-dir ./performance/projects \
                --baseline-dir ./performance/baselines/1.4.6 \
                --out-dir ./performance/results

运行器集成Hyperfine基准测试工具,确保时间测量的准确性,并处理各种边界情况和异常。

持续集成集成

性能测试完全集成到GitHub Actions工作流中:

  1. 建模工作流:在新版本发布后自动运行,建立性能基准
  2. 采样工作流:在每次提交时运行,检测性能回归
  3. 结果报告:自动生成详细的性能报告和回归分析

测试场景扩展机制

dbt-core的性能测试框架支持灵活的场景扩展:

# 项目配置文件示例
name: 'performance_test'
version: '1.0.0'
config-version: 2

profile: 'default'
model-paths: ["models"]

target-path: "target"
clean-targets:
  - "target"
  - "dbt_modules"

models:
  materialized: view

新的测试场景可以通过添加项目目录和配置相应的性能指标来扩展,框架会自动识别并纳入测试范围。

异常处理与容错机制

性能测试框架包含完善的异常处理:

  • 超时检测和自动终止
  • 资源泄漏监控
  • 结果验证和完整性检查
  • 环境变量隔离确保测试一致性

性能指标监控

框架监控多个维度的性能指标:

指标类型描述监控频率
执行时间命令运行时间每次运行
CPU使用用户和系统时间每次运行
内存使用峰值内存占用抽样监控
I/O操作磁盘读写次数抽样监控

这种多维度的监控确保能够全面捕获性能变化,而不仅仅是执行时间的变化。

通过这套完善的性能测试与基准测试方法,dbt-core能够确保每个版本都维持高性能标准,及时检测并修复性能回归问题。

持续集成与自动化测试流水线

dbt-core项目构建了一套高度自动化的持续集成与测试流水线,通过GitHub Actions实现了从代码提交到测试执行的完整自动化流程。该流水线采用多阶段并行测试策略,确保代码质量的同时最大化测试效率。

GitHub Actions工作流架构

dbt-core的CI/CD流水线基于GitHub Actions构建,主要配置文件位于.github/workflows/main.yml。该工作流采用模块化设计,包含多个独立的测试任务:

name: Tests and Code Checks
on:
  push:
    branches: ["main", "*.latest", "releases/*"]
  pull_request:
  merge_group:
    types: [checks_requested]
  workflow_dispatch:

工作流触发条件涵盖代码推送、Pull Request、合并组检查以及手动触发等多种场景,确保所有代码变更都经过完整的质量验证。

多维度测试矩阵

dbt-core的测试矩阵设计非常完善,支持多Python版本和多操作系统的组合测试:

测试类型Python版本操作系统并行策略
单元测试3.9-3.13Ubuntu单机执行
集成测试3.9-3.13Ubuntu5组并行
跨平台测试3.9Windows/macOS分组执行

mermaid

Tox测试环境管理

项目使用Tox进行测试环境管理,tox.ini配置文件定义了清晰的测试环境:

[tox]
skipsdist = True
envlist = unit,integration

[testenv:{unit,py38,py39,py310,py311,py}]
description = unit testing
download = true
skip_install = true
commands =
  {envpython} -m pytest --cov=core --cov-report=xml {posargs} tests/unit

[testenv:{integration,py38-integration,py39-integration,py310-integration,py311-integration,py-integration}]
description = functional testing
download = true
skip_install = true
commands =
  {envpython} -m pytest --cov=core --cov-append --cov-report=xml {posargs} tests/functional

Tox配置支持单元测试和集成测试两种环境,每个环境都包含完整的依赖安装和测试执行流程。

并行测试执行策略

集成测试采用智能并行化策略,通过pytest-split插件实现测试用例的均匀分发:

env:
  PYTHON_INTEGRATION_TEST_WORKERS: 5

steps:
  - name: Run integration tests
    uses: nick-fields/retry@v3
    with:
      command: tox -- --ddtrace
    env:
      PYTEST_ADDOPTS: ${{ format('--splits {0} --group {1}', env.PYTHON_INTEGRATION_TEST_WORKERS, matrix.split-group) }}

这种并行策略将集成测试平均分配到5个worker中执行,显著缩短了整体测试时间。每个worker运行独立的测试子集,通过--splits--group参数控制测试分发。

数据库服务容器化

集成测试使用Docker容器提供PostgreSQL数据库服务,确保测试环境的一致性:

services:
  postgres:
    image: postgres
    env:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: postgres
    options: >-
      --health-cmd pg_isready
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5
    ports:
      - 5432:5432

数据库容器配置了健康检查机制,确保测试执行前数据库服务已经完全就绪。

测试覆盖率监控

项目集成Codecov进行测试覆盖率监控,在关键Python版本上上传覆盖率报告:

- name: Upload Unit Test Coverage to Codecov
  if: ${{ matrix.python-version == '3.11' }}
  uses: codecov/codecov-action@v5
  with:
    token: ${{ secrets.CODECOV_TOKEN }}
    flags: unit

覆盖率报告区分单元测试和集成测试,通过不同的flag进行标识,便于分析不同测试类型的覆盖情况。

重试机制与错误处理

测试流水线实现了智能重试机制,对于可能因环境问题导致的测试失败进行自动重试:

- name: Run integration tests
  uses: nick-fields/retry@v3
  with:
    timeout_minutes: 30
    max_attempts: 3
    command: tox -- --ddtrace

重试配置包括超时时间(30分钟)和最大重试次数(3次),有效处理临时性的网络或环境问题。

日志收集与归档

测试执行过程中产生的日志文件会被自动收集和归档:

- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: logs_${{ matrix.python-version }}_${{ matrix.os }}_${{ matrix.split-group }}_${{ steps.date.outputs.date }}
    path: ./logs

日志文件按测试环境、Python版本、操作系统和测试分组进行命名,便于问题排查和调试。

跨平台测试支持

流水线支持Windows、macOS和Linux三大操作系统的测试:

integration-mac-windows:
  name: (${{ matrix.split-group }}) integration test / python ${{ matrix.python-version }} / ${{ matrix.os }}
  runs-on: ${{ matrix.os }}
  strategy:
    include: ${{ fromJson(needs.integration-metadata.outputs.include) }}

跨平台测试确保dbt-core在不同操作系统环境下都能正常工作,提高了项目的可移植性和兼容性。

性能监控与追踪

集成测试集成了Datadog APM进行性能监控:

env:
  DD_CIVISIBILITY_AGENTLESS_ENABLED: true
  DD_API_KEY: ${{ secrets.DATADOG_API_KEY }}
  DD_SITE: datadoghq.com
  DD_ENV: ci
  DD_SERVICE: ${{ github.event.repository.name }}

性能监控帮助开发团队识别测试过程中的性能瓶颈和异常行为。

通过这套完善的持续集成与自动化测试流水线,dbt-core项目确保了代码质量的高度一致性,实现了快速反馈的开发循环,为项目的稳定性和可靠性提供了坚实保障。

总结

dbt-core通过分层测试架构、完善的测试用例设计、性能基准测试方法和高度自动化的持续集成流水线,构建了全面的质量保障体系。该体系采用单元测试与集成测试相结合的策略,支持多Python版本和多操作系统的组合测试,并集成智能并行化、覆盖率监控、重试机制和跨平台测试等功能。这套体系确保了代码质量的高度一致性,实现了快速反馈的开发循环,为dbt-core的稳定性和可靠性提供了坚实保障,使项目能够维持高性能标准并及时检测修复问题。

【免费下载链接】dbt-core dbt-labs/dbt-core: 是一个基于 Python 语言的数据建模和转换工具,可以方便地实现数据仓库的建模和转换等功能。该项目提供了一个简单易用的数据建模和转换工具,可以方便地实现数据仓库的建模和转换等功能,同时支持多种数据仓库和编程语言。 【免费下载链接】dbt-core 项目地址: https://gitcode.com/GitHub_Trending/db/dbt-core

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值