dbt Core

注意

本文介绍 dbt Core,它是适用于本地开发计算机的一个 dbt 版本,用来与 Azure Databricks 工作区中的 Databricks SQL 和 Azure Databricks 群集交互。 若要改用 dbt 的托管版本(称为 dbt Cloud),或使用 Partner Connect 在工作区中快速创建 SQL 仓库,然后将其连接到 dbt Cloud,请参阅 dbt Cloud

dbt(数据编译工具)是一种开发环境,它使数据分析师和数据工程师能够通过编写 select 语句来转换数据。 dbt 可将这些 select 语句转换为表和视图。 dbt 将代码编译为原始 SQL,然后在 Azure Databricks 中指定的数据库上运行该代码。 dbt 支持版本控制、文档、模块化等协作编码模式和最佳做法。 有关详细信息,请参阅 dbt 网站上的 dbt 究竟是什么?适用于所有人的分析工程:dbt 云中的 Databricks

dbt 不会提取或加载数据。 dbt 使用“加载后转换”体系结构,仅专注于转换步骤。 dbt 假定数据库中已有数据的副本。

本文重点介绍如何使用 dbt Core。 dbt Core 使你能够在本地开发计算机上所选的文本编辑器或 IDE 中编写 dbt 代码,然后从命令行运行 dbt。 dbt Core 包括 dbt 命令行接口 (CLI)。 dbt CLI 是一个免费的开放源代码工具。

也可使用名为 dbt Cloud 的托管版本 dbt。 dbt Cloud 为计划作业、CI/CD、提供文档、监视和警报以及集成开发环境 (IDE) 提供统包支持。 有关详细信息,请参阅 dbt Cloud。 dbt Cloud 开发人员计划提供一个免费的开发人员席位;此外,也可以使用团队和企业付费计划。 有关详细信息,请参阅 dbt 网站上的 dbt 定价

由于 dbt Core 和 dbt Cloud 可以使用托管的 git 存储库(例如,在 GitHub、GitLab 或 BitBucket 上),因此可以使用 dbt Core 创建 dbt 项目,然后使其可供 dbt Cloud 用户使用。 有关详细信息,请参阅 dbt 网站上的创建 dbt 项目使用现有项目

有关 dbt 的一般概述,请观看以下 YouTube 视频(26 分钟)。

要求

安装 dbt Core 之前,必须在本地开发计算机上安装以下工具:

  • Python 3.7 或更高版本
  • 用于创建 Python 虚拟环境的实用工具(例如 pipenv

步骤1:创建并激活 Python 虚拟环境

在本步骤中,需要使用 pipenv 创建 pipenv 。 建议使用 Python 虚拟环境,因为它将包版本和代码依赖项隔离到该特定环境,而不管其他环境中的包版本和代码依赖项。 这有助于减少意外的包版本不匹配和代码依赖项冲突。

  1. 从终端切换到空目录,然后创建该目录(如有必要)。 此过程会在用户主目录的根目录中创建名为 dbt_demo 的空目录。

    Unix、linux、macos

    mkdir ~/dbt_demo
    cd ~/dbt_demo
    

    Windows

    mkdir %USERPROFILE%\dbt_demo
    cd %USERPROFILE%\dbt_demo
    
  2. 在空目录中,创建包含以下内容的名为 Pipfile 的文件。 此 Pipfile 指示 使用 Python 版本 3.8.6。 如果使用不同的版本,请将 3.8.6 替换为版本号。

    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"
    
    [packages]
    dbt-databricks = "*"
    
    [requires]
    python_version = "3.8.6"
    

    注意

    上面的行 dbt-databricks = "*" 指示 pipenv 使用最新版本的 dbt-databricks 包。 在生产方案中,应将 * 替换为你要使用的特定版本的包。 请参阅 Python 包索引 (PyPI) 网站上的 dbt-databricks 发行历史记录

  3. 通过运行 pipenv 并指定要使用的 Python 版本,在此目录中创建 Python 虚拟环境。 此命令指定 Python 版本 3.8.6。 如果使用不同的版本,请将 3.8.6 替换为版本号:

    pipenv --python 3.8.6
    
  4. 结合 install 选项运行 pipenv 来安装 dbt Databricks 适配器。 这会在 Pipfile 中安装包,其中包括来自 PyPI 的 dbt Databricks 适配器包 dbt-databricks。 dbt Databricks 适配器包会自动安装 dbt Core 和其他依赖项。

    重要

    如果本地开发计算机使用以下任何操作系统,则必须先完成附加步骤:CentOS、MacOS、Ubuntu、Debian 和 Windows。 请参阅 dbt Labs 网站上的使用 pip 安装 dbt 中的“我的操作系统是否需要满足先决条件”部分。

    pipenv install
    
  5. 通过运行 pipenv shell 激活此虚拟环境。 为了确认激活,终端会在提示符之前显示 (dbt_demo)。 虚拟环境开始使用指定版本的 Python,并隔离此新环境中的所有包版本和代码依赖项。

    pipenv shell
    

    注意

    若要停用此虚拟环境,请运行 exit(dbt_demo) 从提示符之前消失。 如果在停用此虚拟环境的情况下运行 python --versionpip list,则可能会看到不同版本的 Python 和/或不同的可用包或包版本列表。

  6. 使用 --version 选项运行 python,确认虚拟环境正在运行预期的 Python 版本。

    python --version
    

    如果显示意外的 Python 版本,请确保通过运行 pipenv shell 激活虚拟环境。

  7. 结合 --version 选项运行 dbt,确认虚拟环境正在运行预期的 dbt 和 dbt Databricks 适配器版本。

    dbt --version
    

    如果显示了意外的 dbt 或 dbt Databricks 适配器版本,请确保运行 pipenv shell 来激活虚拟环境。 如果仍显示意外版本,请尝试在激活虚拟环境后再次安装 dbt 或 dbt Databricks 适配器。

步骤 2:创建 dbt 项目并指定和测试连接设置

在本步骤中,需要创建一个 dbt 项目(即需要使用 dbt 的相关目录和文件的集合)。 然后,配置连接配置文件,其中包含与 Azure Databricks 群集和/或 SQL 仓库的连接设置。 为了增强安全性,默认情况下 dbt 项目和配置文件存储在不同的位置。

提示

可连接到现有群集或 SQL 仓库,也可创建新的群集或仓库。

  • 对于多个 dbt 项目、在团队中使用 dbt 或开发用例,连接到现有群集或 SQL 仓库可提高效率。
  • 创建新的群集或 SQL 仓库可在生产用例中独立运行单个 dbt 项目,并在该 dbt 项目不运行时利用自动终止来节省成本。

使用 Azure Databricks 创建新的群集或 SQL 仓库,然后从 dbt 配置文件引用新创建的或现有的群集或 SQL 仓库。

  1. 在虚拟环境仍处于激活状态的情况下,结合项目的名称运行 dbt init 命令。 此过程创建名为 my_dbt_demo 的项目。

    dbt init my_dbt_demo
    
  2. 当系统提示是使用 databricks 还是 spark 数据库时,请输入对应于 databricks 的数字。

  3. 当系统提示输入 host 值时:

  4. 当系统提示输入 http_path 值时:

  5. 当系统提示输入 token 时,请输入你的 Azure Databricks 个人访问令牌值。

  6. 出现提示时,请输入 schemathreads 的所需值。

  7. dbt 将条目写入 profiles.yml 文件。 dbt init 命令的输出中列出了此文件的位置。 以后还可通过运行 dbt debug --config-dir 命令列出此位置。 现在可以打开此文件以检查和验证其内容。

  8. 运行 dbt debug 命令,确认连接详细信息正确无误。

    重要

    首先确保你的群集或 SQL 仓库正在运行。

    应该会看到与下面类似的输出:

    dbt debug
    
    ...
    Configuration:
      profiles.yml file [OK found and valid]
      dbt_project.yml file [OK found and valid]
    
    Required dependencies:
     - git [OK found]
    
    Connection:
      ...
      Connection test: OK connection ok
    

步骤 3:创建和运行模型

在本步骤中,需要使用喜欢的文本编辑器创建模型,这些模型是 语句,会根据同一数据库中的现有数据在数据库中创建一个新视图(默认行为)或一个新表。 此过程根据示例数据集 (databricks-datasets) 中的示例 diamonds 表创建模型,如 _ 的“创建表”部分所述。 此过程假定已在工作区的 default 数据库中创建此表。

  1. 在项目的 models 目录中,创建包含以下 SQL 语句的名为 diamonds_four_cs.sql 的文件。 此语句仅从 diamonds 表中选择每颗钻石的克拉数、切工、颜色和透明度详细信息。 config 块指示 dbt 根据此语句在数据库中创建表。

    {{ config(
      materialized='table',
      file_format='delta'
    ) }}
    
    select carat, cut, color, clarity
    from diamonds
    

    提示

    有关其他 config 选项(例如使用差异文件格式和 merge 增量策略)的信息,请参阅 dbt 网站上的 config和 GitHub 中 dbt-labs/dbt-spark 存储库中“merge”的“模型配置”和“增量模型”部分。

  2. 在项目的 models 目录中,创建第二个包含以下 SQL 语句的名为 diamonds_list_colors.sql 的文件。 此语句从 colors 表中的 diamonds_four_cs 列中选择唯一值,按字母顺序依次对结果进行排序。 由于没有 config 块,此模型将指示 dbt 根据此语句在数据库中创建视图。

    select distinct color
    from {{ ref('diamonds_four_cs') }}
    sort by color asc
    
  3. 在项目的 models 目录中,创建第三个包含以下 SQL 语句的名为 diamonds_prices.sql 的文件。 此语句按颜色计算钻石的平均价格,并按平均价格从高到低对结果进行排序。 此模型指示 dbt 根据此语句在数据库中创建视图。

    select color, avg(price) as price
    from diamonds
    group by color
    order by price desc
    
  4. 激活虚拟环境后,使用上述三个文件的路径运行 dbt run 命令。 在 default 数据库中(如 profiles.yml 文件中指定),dbt 会创建一个名为 diamonds_four_cs 的表和两个名为 diamonds_list_colorsdiamonds_prices 的视图。 dbt 从相关的 .sql 文件名获取这些视图和表名称。

    dbt run --model models/diamonds_four_cs.sql models/diamonds_list_colors.sql models/diamonds_prices.sql
    
    ...
    ... | 1 of 3 START table model default.diamonds_four_cs.................... [RUN]
    ... | 1 of 3 OK created table model default.diamonds_four_cs............... [OK ...]
    ... | 2 of 3 START view model default.diamonds_list_colors................. [RUN]
    ... | 2 of 3 OK created view model default.diamonds_list_colors............ [OK ...]
    ... | 3 of 3 START view model default.diamonds_prices...................... [RUN]
    ... | 3 of 3 OK created view model default.diamonds_prices................. [OK ...]
    ... |
    ... | Finished running 1 table model, 2 view models ...
    
    Completed successfully
    
    Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3
    
  5. 运行以下 SQL 代码,列出有关新视图的信息,并选择表和视图中所有行。

    如果要连接到群集,可以从连接到群集的笔记本中运行此 SQL 代码,同时指定 SQL 作为笔记本的默认语言。 如果要连接到 SQL 仓库,可以从查询运行此 SQL 代码。

    SHOW views IN default;
    
    +-----------+----------------------+-------------+
    | namespace | viewName             | isTemporary |
    +===========+======================+=============+
    | default   | diamonds_list_colors | false       |
    +-----------+----------------------+-------------+
    | default   | diamonds_prices      | false       |
    +-----------+----------------------+-------------+
    
    SELECT * FROM diamonds_four_cs;
    
    +-------+---------+-------+---------+
    | carat | cut     | color | clarity |
    +=======+=========+=======+=========+
    | 0.23  | Ideal   | E     | SI2     |
    +-------+---------+-------+---------+
    | 0.21  | Premium | E     | SI1     |
    +-------+---------+-------+---------+
    ...
    
    SELECT * FROM diamonds_list_colors;
    
    +-------+
    | color |
    +=======+
    | D     |
    +-------+
    | E     |
    +-------+
    ...
    
    SELECT * FROM diamonds_prices;
    
    +-------+---------+
    | color | price   |
    +=======+=========+
    | J     | 5323.82 |
    +-------+---------+
    | I     | 5091.87 |
    +-------+---------+
    ...
    

步骤 4:创建并运行更复杂的模型

在此步骤中,你将为一组相关数据表创建更复杂的模型。 这些数据表包含有关虚拟的体育联赛的信息,其中三支队伍需要在一个赛季中完成六场比赛。 此过程将创建数据表、创建模型并运行模型。

  1. 运行以下 SQL 代码以创建必要的数据表。

    如果要连接到群集,可以从连接到群集的笔记本中运行此 SQL 代码,同时指定 SQL 作为笔记本的默认语言。 如果要连接到 SQL 仓库,可以从查询运行此 SQL 代码。

    本步骤中的表和视图以 zzz_ 开头,有助于在本示例中识别它们。 对于自己的表和视图,无需遵循此模式。

    DROP TABLE IF EXISTS zzz_game_opponents;
    DROP TABLE IF EXISTS zzz_game_scores;
    DROP TABLE IF EXISTS zzz_games;
    DROP TABLE IF EXISTS zzz_teams;
    
    CREATE TABLE zzz_game_opponents (
    game_id INT,
    home_team_id INT,
    visitor_team_id INT
    ) USING DELTA;
    
    INSERT INTO zzz_game_opponents VALUES (1, 1, 2);
    INSERT INTO zzz_game_opponents VALUES (2, 1, 3);
    INSERT INTO zzz_game_opponents VALUES (3, 2, 1);
    INSERT INTO zzz_game_opponents VALUES (4, 2, 3);
    INSERT INTO zzz_game_opponents VALUES (5, 3, 1);
    INSERT INTO zzz_game_opponents VALUES (6, 3, 2);
    
    /*
    +---------+--------------+-----------------+
    | game_id | home_team_id | visitor_team_id |
    +=========+==============+=================+
    | 1       | 1            | 2               |
    +---------+--------------+-----------------+
    | 2       | 1            | 3               |
    +---------+--------------+-----------------+
    | 3       | 2            | 1               |
    +---------+--------------+-----------------+
    | 4       | 2            | 3               |
    +---------+--------------+-----------------+
    | 5       | 3            | 1               |
    +---------+--------------+-----------------+
    | 6       | 3            | 2               |
    +---------+--------------+-----------------+
    */
    
    CREATE TABLE zzz_game_scores (
    game_id INT,
    home_team_score INT,
    visitor_team_score INT
    ) USING DELTA;
    
    INSERT INTO zzz_game_scores VALUES (1, 4, 2);
    INSERT INTO zzz_game_scores VALUES (2, 0, 1);
    INSERT INTO zzz_game_scores VALUES (3, 1, 2);
    INSERT INTO zzz_game_scores VALUES (4, 3, 2);
    INSERT INTO zzz_game_scores VALUES (5, 3, 0);
    INSERT INTO zzz_game_scores VALUES (6, 3, 1);
    
    /*
    +---------+-----------------+--------------------+
    | game_id | home_team_score | visitor_team_score |
    +=========+=================+====================+
    | 1       | 4               | 2                  |
    +---------+-----------------+--------------------+
    | 2       | 0               | 1                  |
    +---------+-----------------+--------------------+
    | 3       | 1               | 2                  |
    +---------+-----------------+--------------------+
    | 4       | 3               | 2                  |
    +---------+-----------------+--------------------+
    | 5       | 3               | 0                  |
    +---------+-----------------+--------------------+
    | 6       | 3               | 1                  |
    +---------+-----------------+--------------------+
    */
    
    CREATE TABLE zzz_games (
    game_id INT,
    game_date DATE
    ) USING DELTA;
    
    INSERT INTO zzz_games VALUES (1, '2020-12-12');
    INSERT INTO zzz_games VALUES (2, '2021-01-09');
    INSERT INTO zzz_games VALUES (3, '2020-12-19');
    INSERT INTO zzz_games VALUES (4, '2021-01-16');
    INSERT INTO zzz_games VALUES (5, '2021-01-23');
    INSERT INTO zzz_games VALUES (6, '2021-02-06');
    
    /*
    +---------+------------+
    | game_id | game_date  |
    +=========+============+
    | 1       | 2020-12-12 |
    +---------+------------+
    | 2       | 2021-01-09 |
    +---------+------------+
    | 3       | 2020-12-19 |
    +---------+------------+
    | 4       | 2021-01-16 |
    +---------+------------+
    | 5       | 2021-01-23 |
    +---------+------------+
    | 6       | 2021-02-06 |
    +---------+------------+
    */
    
    CREATE TABLE zzz_teams (
    team_id INT,
    team_city VARCHAR(15)
    ) USING DELTA;
    
    INSERT INTO zzz_teams VALUES (1, "San Francisco");
    INSERT INTO zzz_teams VALUES (2, "Seattle");
    INSERT INTO zzz_teams VALUES (3, "Amsterdam");
    
    /*
    +---------+---------------+
    | team_id | team_city     |
    +=========+===============+
    | 1       | San Francisco |
    +---------+---------------+
    | 2       | Seattle       |
    +---------+---------------+
    | 3       | Amsterdam     |
    +---------+---------------+
    */
    
  2. 在项目的 models 目录中,创建包含以下 SQL 语句的名为 zzz_game_details.sql 的文件。 此语句会创建一个表,该表提供每场比赛的详细信息,例如队伍名称和分数。 config 块指示 dbt 根据此语句在数据库中创建表。

    -- Create a table that provides full details for each game, including
    -- the game ID, the home and visiting teams' city names and scores,
    -- the game winner's city name, and the game date.
    
    {{ config(
      materialized='table',
      file_format='delta'
    ) }}
    
    -- Step 4 of 4: Replace the visitor team IDs with their city names.
    select
      game_id,
      home,
      t.team_city as visitor,
      home_score,
      visitor_score,
      -- Step 3 of 4: Display the city name for each game's winner.
      case
        when
          home_score > visitor_score
            then
              home
        when
          visitor_score > home_score
            then
              t.team_city
      end as winner,
      game_date as date
    from (
      -- Step 2 of 4: Replace the home team IDs with their actual city names.
      select
        game_id,
        t.team_city as home,
        home_score,
        visitor_team_id,
        visitor_score,
        game_date
      from (
        -- Step 1 of 4: Combine data from various tables (for example, game and team IDs, scores, dates).
        select
          g.game_id,
          go.home_team_id,
          gs.home_team_score as home_score,
          go.visitor_team_id,
          gs.visitor_team_score as visitor_score,
          g.game_date
        from
          zzz_games as g,
          zzz_game_opponents as go,
          zzz_game_scores as gs
        where
          g.game_id = go.game_id and
          g.game_id = gs.game_id
      ) as all_ids,
        zzz_teams as t
      where
        all_ids.home_team_id = t.team_id
    ) as visitor_ids,
      zzz_teams as t
    where
      visitor_ids.visitor_team_id = t.team_id
    order by game_date desc
    
  3. 在项目的 models 目录中,创建包含以下 SQL 语句的名为 zzz_win_loss_records.sql 的文件。 此语句会创建一个视图,视图中会列出该赛季队伍的胜负记录。

    -- Create a view that summarizes the season's win and loss records by team.
    
    -- Step 2 of 2: Calculate the number of wins and losses for each team.
    select
      winner as team,
      count(winner) as wins,
      -- Each team played in 4 games.
      (4 - count(winner)) as losses
    from (
      -- Step 1 of 2: Determine the winner and loser for each game.
      select
        game_id,
        winner,
        case
          when
            home = winner
              then
                visitor
          else
            home
        end as loser
      from {{ ref('zzz_game_details') }}
    )
    group by winner
    order by wins desc
    
  4. 激活虚拟环境后,使用上述两个文件的路径运行 dbt run 命令。 在 default 数据库中(如 profiles.yml 文件中指定),dbt 会创建一个名为 zzz_game_details 的表和一个名为 zzz_win_loss_records 的视图。 dbt 从相关的 .sql 文件名获取这些视图和表名称。

    dbt run --model models/zzz_game_details.sql models/zzz_win_loss_records.sql
    
    ...
    ... | 1 of 2 START table model default.zzz_game_details.................... [RUN]
    ... | 1 of 2 OK created table model default.zzz_game_details............... [OK ...]
    ... | 2 of 2 START view model default.zzz_win_loss_records................. [RUN]
    ... | 2 of 2 OK created view model default.zzz_win_loss_records............ [OK ...]
    ... |
    ... | Finished running 1 table model, 1 view model ...
    
    Completed successfully
    
    Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
    
  5. 运行以下 SQL 代码,列出有关新视图的信息,并选择表和视图中所有行。

    如果要连接到群集,可以从连接到群集的笔记本中运行此 SQL 代码,同时指定 SQL 作为笔记本的默认语言。 如果要连接到 SQL 仓库,可以从查询运行此 SQL 代码。

    SHOW VIEWS FROM default LIKE 'zzz_win_loss_records';
    
    +-----------+----------------------+-------------+
    | namespace | viewName             | isTemporary |
    +===========+======================+=============+
    | default   | zzz_win_loss_records | false       |
    +-----------+----------------------+-------------+
    
    SELECT * FROM zzz_game_details;
    
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | game_id | home          | visitor       | home_score | visitor_score | winner        | date       |
    +=========+===============+===============+============+===============+===============+============+
    | 1       | San Francisco | Seattle       | 4          | 2             | San Francisco | 2020-12-12 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | 2       | San Francisco | Amsterdam     | 0          | 1             | Amsterdam     | 2021-01-09 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | 3       | Seattle       | San Francisco | 1          | 2             | San Francisco | 2020-12-19 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | 4       | Seattle       | Amsterdam     | 3          | 2             | Seattle       | 2021-01-16 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | 5       | Amsterdam     | San Francisco | 3          | 0             | Amsterdam     | 2021-01-23 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    | 6       | Amsterdam     | Seattle       | 3          | 1             | Amsterdam     | 2021-02-06 |
    +---------+---------------+---------------+------------+---------------+---------------+------------+
    
    SELECT * FROM zzz_win_loss_records;
    
    +---------------+------+--------+
    | team          | wins | losses |
    +===============+======+========+
    | Amsterdam     | 3    | 1      |
    +---------------+------+--------+
    | San Francisco | 2    | 2      |
    +---------------+------+--------+
    | Seattle       | 1    | 3      |
    +---------------+------+--------+
    

步骤 5:创建并运行测试

在此步骤中,你将创建测试,这些测试是有关模型的断言。 运行这些测试时,dbt 会告诉你项目中的每个测试是通过还是失败。

有两种类型的测试。 架构测试,在 YAML 中应用,返回未通过断言的记录数。 如果此数字为零,则所有记录都通过,因此测试也通过。 数据测试,它是必须返回零条记录以通过的特定查询。

  1. 在项目的 models 目录中,创建包含以下内容的名为 schema.yml 的文件。 此文件包括用于确定指定列是否具有唯一值、是否不为 null、是否仅具有指定值或组合的架构测试。

    version: 2
    
    models:
      - name: zzz_game_details
        columns:
          - name: game_id
            tests:
              - unique
              - not_null
          - name: home
            tests:
              - not_null
              - accepted_values:
                  values: ['Amsterdam', 'San Francisco', 'Seattle']
          - name: visitor
            tests:
              - not_null
              - accepted_values:
                  values: ['Amsterdam', 'San Francisco', 'Seattle']
          - name: home_score
            tests:
              - not_null
          - name: visitor_score
            tests:
              - not_null
          - name: winner
            tests:
              - not_null
              - accepted_values:
                  values: ['Amsterdam', 'San Francisco', 'Seattle']
          - name: date
            tests:
              - not_null
      - name: zzz_win_loss_records
        columns:
          - name: team
            tests:
              - unique
              - not_null
              - relationships:
                  to: ref('zzz_game_details')
                  field: home
          - name: wins
            tests:
              - not_null
          - name: losses
            tests:
              - not_null
    
  2. 在项目的 tests 目录中,创建包含以下 SQL 语句的名为 zzz_game_details_check_dates.sql 的文件。 此文件包含一个数据测试,用于确定常规赛季外是否进行了任何比赛。

    -- This season's games happened between 2020-12-12 and 2021-02-06.
    -- For this test to pass, this query must return no results.
    
    select date
    from {{ ref('zzz_game_details') }}
    where date < '2020-12-12'
    or date > '2021-02-06'
    
  3. 在项目的 tests 目录中,创建包含以下 SQL 语句的名为 zzz_game_details_check_scores.sql 的文件。 此文件包含一个数据测试,用于确定任何分数是否为负或者任何比赛是否打平。

    -- This sport allows no negative scores or tie games.
    -- For this test to pass, this query must return no results.
    
    select home_score, visitor_score
    from {{ ref('zzz_game_details') }}
    where home_score < 0
    or visitor_score < 0
    or home_score = visitor_score
    
  4. 在项目的 tests 目录中,创建包含以下 SQL 语句的名为 zzz_win_loss_records_check_records.sql 的文件。 此文件包含一个数据测试,用于确定任何队伍是否有负数的胜场或败场记录、是否有超过进行比赛数的胜负记录,或者进行的比赛数是否多于允许的比赛数。

    -- Each team participated in 4 games this season.
    -- For this test to pass, this query must return no results.
    
    select wins, losses
    from {{ ref('zzz_win_loss_records') }}
    where wins < 0 or wins > 4
    or losses < 0 or losses > 4
    or (wins + losses) > 4
    
  5. 激活虚拟环境后,使用 models/schema.yml 文件中两个模型的 --schema 选项和名称运行 dbt test 命令,以运行为这些模型指定的测试。

    dbt test --schema --models zzz_game_details zzz_win_loss_records
    
    ...
    ... | 1 of 15 START test accepted_values_zzz_game_details_home__Amsterdam__San_Francisco__Seattle [RUN]
    ... | 1 of 15 PASS accepted_values_zzz_game_details_home__Amsterdam__San_Francisco__Seattle [PASS ...]
    ...
    ... |
    ... | Finished running 15 tests ...
    
    Completed successfully
    
    Done. PASS=15 WARN=0 ERROR=0 SKIP=0 TOTAL=15
    
  6. 使用 --data 选项运行 dbt test 命令,以在项目的 tests 目录中运行测试。

    dbt test --data
    
    ...
    ... | 1 of 3 START test zzz_game_details_check_dates....................... [RUN]
    ... | 1 of 3 PASS zzz_game_details_check_dates............................. [PASS ...]
    ...
    ... |
    ... | Finished running 3 tests ...
    
    Completed successfully
    
    Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3
    

步骤 6:清理

可以通过运行以下 SQL 代码来删除为此示例创建的表和视图。

如果要连接到群集,可以从连接到群集的笔记本中运行此 SQL 代码,同时指定 SQL 作为笔记本的默认语言。 如果要连接到 SQL 仓库,可以从查询运行此 SQL 代码。

DROP TABLE zzz_game_opponents;
DROP TABLE zzz_game_scores;
DROP TABLE zzz_games;
DROP TABLE zzz_teams;
DROP TABLE zzz_game_details;
DROP VIEW zzz_win_loss_records;

DROP TABLE diamonds;
DROP TABLE diamonds_four_cs;
DROP VIEW diamonds_list_colors;
DROP VIEW diamonds_prices;

后续步骤

  • 详细了解 dbt 模型
  • 详细了解如何测试 dbt 项目。
  • 了解如何使用 Jinja(模板化语言)在 dbt 项目中对 SQL 进行编程。
  • 了解 dbt 最佳做法
  • 了解 dbt Cloud(托管版本的 dbt)。

疑难解答

本部分介绍如何解决将 dbt Core 与 Azure Databricks 配合使用时出现的常见问题。

常规故障排除

请参阅 dbt Labs 网站上的获取帮助

其他资源