dbt Seeds:CSV 檔案匯入與管理

Seeds 是 dbt 專案中的 CSV 檔案,通常放在 seeds/ 目錄下。透過 dbt seed 指令,與 dbt 可以將這些 CSV 檔案直接載入到資料庫中成為 Table。

適用場景

Seeds 最適合用來管理靜態的、小型的、不常變動的參考資料 (Lookup Tables),例如:

  • 國家代碼對照表 (Country Codes)
  • 行銷活動分類表 (Campaign Mapping)
  • 部門組織代碼
  • 排除名單 (Exclusion Lists)

不適用場景

  • 原始數據 (Raw Data):不要把幾百萬筆的交易紀錄放進 seeds。請使用 EL 工具載入並用 dbt source 引用。
  • 敏感資訊 (PII):seeds 檔案會被 commit 到 git,所以絕對不要放個資或密碼。

如何使用 Seeds

1. 準備 CSV 檔案

建立一個 CSV 檔案 country_codes.csv,並放入 seeds/ 資料夾:

country_code,country_name
US,United States
TW,Taiwan
JP,Japan

2. 執行 dbt seed

在終端機執行:

dbt seed

dbt 會讀取 seeds/ 下的所有 CSV,分析欄位型別,並在資料庫中執行 CREATE TABLEINSERT

預設情況下,table 名稱會與檔名相同 (此例為 country_codes)。

3. 在 Model 中引用

載入成功後,你可以像引用其他 model 一樣,使用 ref() 來引用 seed:

-- models/customers_with_country_name.sql

select
    c.id,
    c.name,
    m.country_name
from {{ ref('customers') }} c
left join {{ ref('country_codes') }} m
  on c.country_code = m.country_code

設定 Seeds

你可以在 dbt_project.yml 中設定 seeds 的型別與行為:

seeds:
  my_dbt_project:
    country_codes:
      # 強制指定欄位型別 (預設 dbt 會自動猜測,但有時會猜錯)
      +column_types:
        country_code: varchar(2)
        country_name: varchar(100)

      # 若資料庫已有該表,是否啟用全量覆蓋 (預設為 True)
      +full_refresh: true

進階設定:自訂資料夾與 Table 名稱

除了基本的型別設定,dbt 也允許你彈性地組織檔案結構與自訂資料庫 Table 名稱。

1. 組織 Seeds 資料夾結構

dbt 支援將 seeds 檔案放在 seeds/ 目錄下的任意子資料夾中。當 Seeds 變多時,這對於專案整理非常有幫助。

檔案結構範例

seeds/
  ├── finance/
  │   └── tax_rates.csv
  ├── marketing/
  │   └── campaign_codes.csv
  └── geography/
      └── country_codes.csv

即使檔案放在子資料夾中,在 ref() 引用時依然是直接使用檔名 (不需要加上路徑):

select * from {{ ref('tax_rates') }}
注意:dbt 專案中所有的 seeds 和 models 名稱 (檔名) 必須是全域唯一的。即使在不同資料夾,也不能有兩個名為 tax_rates.csv 的檔案。

2. 自訂 Table Name (Alias)

有時候你希望 CSV 檔名包含版本號或日期以便管理 (例如 campaign_mapping_2023_v2.csv),但希望寫入資料庫的 Table 名稱保持簡潔固定 (例如 campaign_mapping),以免下游報表壞掉。

這時可以使用 alias 設定。你可以在 dbt_project.yml 或各個 seeds 目錄下的 .yml 檔案中設定。

方法一:在 dbt_project.yml 設定

seeds:
  my_dbt_project:
    marketing:
      # 針對特定檔案設定 alias
      campaign_mapping_2023_v2:
        +alias: campaign_mapping

方法二:在 schema.yml (properties file) 設定 (推薦)

這種方式讓設定更靠近檔案,便於維護。

version: 2

seeds:
  - name: campaign_mapping_2023_v2
    config:
      alias: campaign_mapping

如何引用?

重點來了!當你設定了 alias 後,在其他 model 使用 ref() 時,仍然要使用「原始檔名」,而不是 alias 名稱。

-- 正確:引用檔名
select * from {{ ref('campaign_mapping_2023_v2') }}

-- 錯誤:不能直接引用 alias
-- select * from {{ ref('campaign_mapping') }}

dbt 編譯時會自動將其轉換為資料庫中實際的 Table 名稱 (campaign_mapping)。這樣的好處是,當你需要換一個新版本的 CSV 檔 (例如 v3) 時,只需要修改 alias 設定,而不需要去修改所有引用它的 SQL 程式碼。

版本控制 (Version Control)

Seeds 的一大優點是資料內容也納入 Git 版本控制。這意味著當你修改了行銷活動的分類邏輯時,這個變更會隨著 Code Review 的流程一起被審核,確保了業務邏輯與程式碼的一致性。

總結

Seeds 提供了一種簡單、版控友好的方式來管理小型靜態資料。善用 Seeds 可以讓你的 dbt 專案更加完整,減少依賴外部不穩定的 mapping table。