Udostępnij za pośrednictwem


Samouczek: tworzenie, uruchamianie i testowanie modeli dbt lokalnie

Ten samouczek przeprowadzi Cię przez proces tworzenia, uruchamiania i testowania modeli dbt lokalnie. Projekty dbt można również uruchamiać jako zadania zadań usługi Azure Databricks. Aby uzyskać więcej informacji, zobacz Use dbt transformations in an Azure Databricks job (Używanie przekształceń dbt w zadaniu usługi Azure Databricks).

Przed rozpoczęciem

Aby wykonać czynności opisane w tym samouczku, musisz najpierw połączyć obszar roboczy usługi Azure Databricks z bazą danych dbt Core. Aby uzyskać więcej informacji, zobacz Nawiązywanie połączenia z bazą danych dbt Core.

Krok 1. Tworzenie i uruchamianie modeli

W tym kroku użyjesz ulubionego edytora tekstów do utworzenia modeli, które są select instrukcjami tworzącymi nowy widok (domyślny) lub nową tabelę w bazie danych na podstawie istniejących danych w tej samej bazie danych. Ta procedura tworzy model na podstawie przykładowej tabeli z przykładowych diamonds zestawów danych.

Użyj poniższego kodu, aby utworzyć tę tabelę.

DROP TABLE IF EXISTS diamonds;

CREATE TABLE diamonds USING CSV OPTIONS (path "/databricks-datasets/Rdatasets/data-001/csv/ggplot2/diamonds.csv", header "true")
  1. W katalogu projektu models utwórz plik o nazwie z diamonds_four_cs.sql następującą instrukcją SQL. Ta instrukcja wybiera tylko karatę, wycięcie, kolor i szczegóły jasności dla każdego diamentu diamonds z tabeli. Blok config instruuje dbt, aby utworzyć tabelę w bazie danych na podstawie tej instrukcji.

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

    Napiwek

    Aby uzyskać dodatkowe config opcje, takie jak używanie formatu pliku delta i merge strategia przyrostowa, zobacz Konfiguracje usługi Databricks w dokumentacji bazy danych.

  2. W katalogu projektu models utwórz drugi plik o nazwie z diamonds_list_colors.sql następującą instrukcją SQL. Ta instrukcja wybiera unikatowe wartości z colors kolumny w diamonds_four_cs tabeli, sortując wyniki w kolejności alfabetycznej najpierw do ostatniego. Ponieważ nie config ma bloku, ten model nakazuje dbt utworzenie widoku w bazie danych na podstawie tej instrukcji.

    select distinct color
    from {{ ref('diamonds_four_cs') }}
    sort by color asc
    
  3. W katalogu projektu models utwórz trzeci plik o nazwie za diamonds_prices.sql pomocą następującej instrukcji SQL. To stwierdzenie określa średnie ceny diamentów według koloru, sortując wyniki według średniej ceny od najwyższej do najniższej. Ten model instruuje dbt, aby utworzyć widok w bazie danych na podstawie tej instrukcji.

    select color, avg(price) as price
    from diamonds
    group by color
    order by price desc
    
  4. Po aktywowaniu środowiska wirtualnego uruchom dbt run polecenie ze ścieżkami do trzech poprzednich plików. default W bazie danych (jak określono w profiles.yml pliku) dbt tworzy jedną tabelę o nazwie i dwa widoki o nazwie diamonds_four_cs diamonds_list_colors i diamonds_prices. Dbt pobiera te nazwy widoków i tabel z powiązanych .sql nazw plików.

    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. Uruchom następujący kod SQL, aby wyświetlić listę informacji o nowych widokach i wybrać wszystkie wiersze z tabeli i widoków.

    Jeśli łączysz się z klastrem, możesz uruchomić ten kod SQL z notesu połączonego z klastrem, określając język SQL jako domyślny język notesu. Jeśli nawiązujesz połączenie z usługą SQL Warehouse, możesz uruchomić ten kod SQL z zapytania.

    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 |
    +-------+---------+
    ...
    

Krok 2. Tworzenie i uruchamianie bardziej złożonych modeli

W tym kroku utworzysz bardziej złożone modele dla zestawu powiązanych tabel danych. Te tabele danych zawierają informacje o fikcyjnej lidze sportowej trzech drużyn rozgrywających sezon sześciu meczów. Ta procedura tworzy tabele danych, tworzy modele i uruchamia modele.

  1. Uruchom następujący kod SQL, aby utworzyć niezbędne tabele danych.

    Jeśli łączysz się z klastrem, możesz uruchomić ten kod SQL z notesu połączonego z klastrem, określając język SQL jako domyślny język notesu. Jeśli nawiązujesz połączenie z usługą SQL Warehouse, możesz uruchomić ten kod SQL z zapytania.

    Tabele i widoki w tym kroku zaczynają się od zzz_ , aby ułatwić ich identyfikację w ramach tego przykładu. Nie musisz przestrzegać tego wzorca dla własnych tabel i widoków.

    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);
    
    -- Result:
    -- +---------+--------------+-----------------+
    -- | 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);
    
    -- Result:
    -- +---------+-----------------+--------------------+
    -- | 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');
    
    -- Result:
    -- +---------+------------+
    -- | 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");
    
    -- Result:
    -- +---------+---------------+
    -- | team_id | team_city     |
    -- +=========+===============+
    -- | 1       | San Francisco |
    -- +---------+---------------+
    -- | 2       | Seattle       |
    -- +---------+---------------+
    -- | 3       | Amsterdam     |
    -- +---------+---------------+
    
  2. W katalogu projektu models utwórz plik o nazwie z zzz_game_details.sql następującą instrukcją SQL. Ta instrukcja tworzy tabelę zawierającą szczegółowe informacje o każdej grze, takie jak nazwy zespołów i wyniki. Blok config instruuje dbt, aby utworzyć tabelę w bazie danych na podstawie tej instrukcji.

    -- 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. W katalogu projektu models utwórz plik o nazwie z zzz_win_loss_records.sql następującą instrukcją SQL. To stwierdzenie tworzy widok, który wyświetla listę rekordów wygranej zespołu w sezonie.

    -- 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. Po aktywowaniu środowiska wirtualnego uruchom dbt run polecenie ze ścieżkami do dwóch poprzednich plików. default W bazie danych (określonej w profiles.yml pliku) dbt tworzy jedną tabelę o nazwie i jeden widok o nazwie zzz_game_details zzz_win_loss_records. Dbt pobiera te nazwy widoków i tabel z powiązanych .sql nazw plików.

    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. Uruchom następujący kod SQL, aby wyświetlić listę informacji o nowym widoku i wybrać wszystkie wiersze z tabeli i widoku.

    Jeśli łączysz się z klastrem, możesz uruchomić ten kod SQL z notesu połączonego z klastrem, określając język SQL jako domyślny język notesu. Jeśli nawiązujesz połączenie z usługą SQL Warehouse, możesz uruchomić ten kod SQL z zapytania.

    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      |
    +---------------+------+--------+
    

Krok 3. Tworzenie i uruchamianie testów

W tym kroku utworzysz testy, które są asercją tworzoną na temat modeli. Po uruchomieniu tych testów dbt informuje, czy każdy test w projekcie przejdzie pomyślnie lub zakończy się niepowodzeniem.

Istnieją dwa typy testów. Testy schematu zastosowane w języku YAML zwracają liczbę rekordów, które nie przechodzą asercji. Jeśli ta liczba jest równa zero, wszystkie rekordy przechodzą, dlatego testy przechodzą pomyślnie. Testy danych to konkretne zapytania, które muszą zwracać zero rekordów do przekazania.

  1. W katalogu projektu models utwórz plik o nazwie schema.yml z następującą zawartością. Ten plik zawiera testy schematu, które określają, czy określone kolumny mają unikatowe wartości, nie mają wartości null, mają tylko określone wartości lub kombinację.

    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. W katalogu projektu tests utwórz plik o nazwie z zzz_game_details_check_dates.sql następującą instrukcją SQL. Ten plik zawiera test danych, aby ustalić, czy jakiekolwiek gry miały miejsce poza sezonem regularnym.

    -- 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. W katalogu projektu tests utwórz plik o nazwie z zzz_game_details_check_scores.sql następującą instrukcją SQL. Ten plik zawiera test danych w celu ustalenia, czy jakiekolwiek wyniki były ujemne, czy jakiekolwiek gry zostały powiązane.

    -- 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. W katalogu projektu tests utwórz plik o nazwie z zzz_win_loss_records_check_records.sql następującą instrukcją SQL. Ten plik zawiera test danych, aby ustalić, czy jakiekolwiek zespoły miały negatywne rekordy wygranej lub przegranej, miały więcej rekordów wygranej lub przegranej niż gry, czy grały więcej gier niż były dozwolone.

    -- 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. Po aktywowaniu środowiska wirtualnego uruchom dbt test polecenie .

    dbt test --models zzz_game_details zzz_win_loss_records
    
    ...
    ... | 1 of 19 START test accepted_values_zzz_game_details_home__Amsterdam__San_Francisco__Seattle [RUN]
    ... | 1 of 19 PASS accepted_values_zzz_game_details_home__Amsterdam__San_Francisco__Seattle [PASS ...]
    ...
    ... |
    ... | Finished running 19 tests ...
    
    Completed successfully
    
    Done. PASS=19 WARN=0 ERROR=0 SKIP=0 TOTAL=19
    

Krok 4. Czyszczenie

Możesz usunąć tabele i widoki utworzone na potrzeby tego przykładu, uruchamiając następujący kod SQL.

Jeśli łączysz się z klastrem, możesz uruchomić ten kod SQL z notesu połączonego z klastrem, określając język SQL jako domyślny język notesu. Jeśli nawiązujesz połączenie z usługą SQL Warehouse, możesz uruchomić ten kod SQL z zapytania.

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;

Rozwiązywanie problemów

Aby uzyskać informacje o typowych problemach podczas korzystania z bazy danych dbt Core z usługą Azure Databricks i sposobu ich rozwiązywania, zobacz Uzyskiwanie pomocy w witrynie internetowej dbt Labs.

Następne kroki

Uruchom projekty dbt Core jako zadania zadań usługi Azure Databricks. Zobacz Używanie przekształceń dbt w zadaniu usługi Azure Databricks.

Dodatkowe zasoby

Zapoznaj się z następującymi zasobami w witrynie internetowej dbt Labs: