DHDataHọc
Lý thuyếtBài 7/85 phút đọc+10 XP

Tài liệu, lineage và môi trường

Bạn sẽ học được

  • Viết mô tả cho model và cột ngay trong schema.yml.
  • Dùng doc block cho nội dung dài dùng chung.
  • Đọc đồ thị lineage để đánh giá ảnh hưởng trước khi sửa.
  • Khai báo exposure để nối bảng dữ liệu với báo cáo thật.
  • Thiết lập CI chạy đúng phần thay đổi bằng state:modified và --defer.

Khái niệm cốt lõi

Một project dbt không có tài liệu sẽ trở thành một mớ bảng mà chỉ người viết đầu tiên hiểu. dbt giải quyết bằng hai thứ đi kèm miễn phí: mô tả khai báo trong YAML, và đồ thị lineage dựng tự động từ ref/source.

Lineage không phải tính năng phụ. Nó là lý do chính khiến ref đáng dùng: mỗi quan hệ phụ thuộc đều được ghi lại và vẽ ra.

Mô tả và doc block

Mô tả ngắn đặt trực tiếp:

code
version: 2

models:
  - name: fct_orders
    description: "Một dòng cho mỗi đơn hàng đã thanh toán hoặc đã giao, theo ngày."
    columns:
      - name: order_id
        description: "Khoá chính, lấy từ raw.orders.id."
      - name: revenue
        description: "Doanh thu sau giảm giá, đơn vị VND."
      - name: segment
        description: "Phân khúc khách hàng tại thời điểm đặt hàng."

Mô tả dài dùng doc block trong file riêng:

code
<!-- models/docs.md -->
{% docs order_status %}

Trạng thái đơn hàng, một trong năm giá trị:

| Giá trị | Ý nghĩa |
| --- | --- |
| pending | Đã tạo, chưa thanh toán |
| paid | Đã thanh toán |
| shipped | Đã giao cho vận chuyển |
| cancelled | Khách huỷ trước khi giao |
| refunded | Đã hoàn tiền |

{% enddocs %}

Dùng lại:

code
      - name: status
        description: "{{ doc('order_status') }}"

Muốn mô tả được đẩy thành comment trong kho, bật:

code
models:
  dbt_shop:
    marts:
      +persist_docs:
        relation: true
        columns: true

Sau đó comment on table marts.fct_orders is '...' xuất hiện trong kho — người dùng SQL trực tiếp cũng thấy.

Xem lineage

code
dbt docs generate
dbt docs serve

Mở http://localhost:8080, chọn fct_orders và xem đồ thị hai chiều:

  • Phía trên: raw.orders, raw.customers → stg_orders, stg_customers → int_orders_enriched → fct_orders.
  • Phía dưới: exposure trỏ tới dashboard doanh thu.

Lineage trả lời ba câu hỏi thực dụng:

  1. Sửa model này thì bảng nào bị ảnh hưởng?
  2. Bảng này lấy số từ đâu?
  3. Bảng này còn ai dùng không?

Nếu một bảng không có downstream và không có exposure, rất có thể nó đã chết.

Trước khi sửa: dbt ls

Không cần mở giao diện để biết ảnh hưởng:

code
dbt ls --select stg_orders+

Kết quả liệt kê mọi model phụ thuộc stg_orders. Nếu danh sách dài và có mart quan trọng, bạn biết phải kiểm tra kỹ hơn. Ngược lại:

code
dbt ls --select +fct_orders

cho biết mọi thứ fct_orders cần để chạy.

Exposure

Exposure nối model với nơi tiêu thụ thật — dashboard, báo cáo, mô hình ML:

code
version: 2

exposures:
  - name: dashboard_doanh_thu
    type: dashboard
    maturity: high
    url: https://bi.congty.vn/dashboards/42
    description: "Dashboard doanh thu hằng ngày của phòng kinh doanh."
    owner:
      name: Phòng Phân tích
      email: analytics@congty.vn
    depends_on:
      - ref('fct_orders')
      - ref('dim_customers')

Lợi ích cụ thể: khi ai đó định xoá dim_customers, lineage hiện ra dashboard đang phụ thuộc nó. Không có exposure, việc xoá trông vô hại.

CI chỉ chạy phần thay đổi

Một project 300 model build toàn bộ mất 45 phút. PR chỉ sửa một file thì không cần chờ ngần đó.

code
dbt build \
  --select state:modified+ \
  --defer \
  --state ./prod-manifest
Thành phầnTác dụng
state:modifiedChỉ model có file thay đổi so với manifest cũ
+Cộng thêm mọi model phụ thuộc
--deferModel không thay đổi thì đọc bảng production thay vì build lại
--stateThư mục chứa manifest.json của lần chạy production gần nhất

Quy trình CI điển hình:

  1. Job đêm trên production chạy dbt build, lưu target/manifest.json thành artifact.
  2. PR mở ra, CI tải artifact đó về thư mục prod-manifest.
  3. CI chạy dbt build --select state:modified+ --defer --state ./prod-manifest.
  4. Chỉ model thay đổi và model phụ thuộc được build, phần còn lại đọc bảng prod.

Thời gian từ 45 phút xuống còn khoảng 3 phút cho một PR nhỏ.

Môi trường và quyền

Môi trườngAi chạyQuyền ghi
devTừng kỹ sưSchema riêng của người đó
ciCI trên PRSchema tạm, xoá sau
prodCI trên nhánh chính hoặc job đêmSchema production, chỉ service account

Không ai chạy --target prod từ máy cá nhân. Nếu quyền cho phép, sớm muộn sẽ có người chạy nhầm.

Thực hành

  1. Thêm description cho ba model và năm cột quan trọng nhất.
  2. Viết một doc block cho cột trạng thái và dùng lại ở hai model.
  3. Chạy dbt docs generate, mở lineage và tìm model không có downstream.
  4. Khai báo một exposure cho dashboard bạn đang phục vụ.
  5. Chạy dbt ls --select state:modified+ sau khi sửa một file để xem danh sách thay đổi.

Lỗi thường gặp

Triệu chứngNguyên nhânCách sửa
dbt docs không hiện modelThiếu trong schema.yml hoặc sai nameTên phải khớp tên file model
Lineage không có nguồnModel đọc bảng bằng tên cứngThay bằng source/ref
Tài liệu lỗi thờiMô tả viết một lần rồi bỏĐưa mô tả vào review PR
CI chậm 45 phút mỗi PRBuild toàn bộDùng state:modified+ và --defer
CI báo lỗi manifest not foundArtifact chưa tải vềThêm bước download artifact
Dashboard gãy sau khi xoá modelKhông khai báo exposureThêm exposure trước khi xoá

Tóm tắt

  • description và doc block biến project thành tài liệu sống.
  • Lineage dựng tự động từ ref/source, không cần vẽ tay.
  • dbt ls --select model+ cho biết ảnh hưởng trước khi sửa.
  • Exposure nối model với dashboard và báo cáo thật.
  • CI dùng state:modified+ và --defer để chỉ build phần thay đổi.

Dùng ← → để chuyển bài