3.1. DBT - Data Build Tool#
3.1.1. DBT overview#
Modeling changes are easy to follow and revert
Explicit dependencies between models
Explore dependencies between models
Data quality tests
Error reporting
Incremental load or fact tables
Track history of dimension tables
Easy to access documantation
3.1.2. DBT setup#
3.1.2.1. For Windows#
3.1.2.1.1. Python#
This is the Python installer you want to use:
https://www.python.org/ftp/python/3.10.7/python-3.10.7-amd64.exe
Please make sure that you work with Python 3.11 as newer versions of python might not be compatible with some of the dbt packages.
3.1.2.1.2. Virtualenv setup#
Here are the commands we executed in this lesson:
cd Desktop
mkdir course
cd course
virtualenv venv
venv\Scripts\activate
3.1.2.2. For Mac#
3.1.2.2.1. iTerm2#
We suggest you to use iTerm2 instead of the built-in Terminal application.
3.1.2.2.2. Homebrew#
Homebrew is a widely popular application manager for the Mac. This is what we use in the class for installing a virtualenv.
Here are the commands we execute in this lesson:
mkdir course
cd course
virtualenv venv
. venv/bin/activate
3.1.2.3. dbt installation#
pip install dbt-core dbt-ADAPTER_NAME
# or : pip install dbt-core dbt-bigquery
# or (run local): pip íntall dbt
#On Linux/Mac: which dbt
dbt setup
Initialize the dbt profiles folder on Mac/Linux:
mkdir ~/.dbt
Initialize the dbt profiles folder on Windows:
mkdir %userprofile%\.dbt
Create a dbt project (all platforms):
dbt init <dbt project path>
Let’s check the DBT config for each platform:
…
Then config the DBT connection
Let’s check DBT connection after config
dbt debug
3.1.2.4. About dbt projects / Folder structure#
Resource |
Description |
---|---|
Each model lives in a single file and contains logic that either transforms raw data into a dataset that is ready for analytics or, more often, is an intermediate step in such a transformation. |
|
A way to capture the state of your mutable tables so you can refer to it later. |
|
CSV files with static data that you can load into your data platform with dbt. |
|
SQL queries that you can write to test the models and resources in your project. |
|
Blocks of code that you can reuse multiple times. |
|
Docs for your project that you can build. |
|
A way to name and describe the data loaded into your warehouse by your Extract and Load tools. |
|
A way to define and describe a downstream use of your project. |
|
A way for you to define metrics for your project. |
|
Groups enable collaborative node organization in restricted collections. |
|
A way to organize analytical SQL queries in your project such as the general ledger from your QuickBooks. |
|
Semantic models define the foundational data relationships in MetricFlow and the dbt Semantic Layer, enabling you to query metrics using a semantic graph. |
|
Saved queries organize reusable queries by grouping metrics, dimensions, and filters into nodes visible in the dbt DAG. |
dbtlearn/
├── README.md
├── dbt_project.yml # Configuration file for the dbt project, specifying project settings and configurations.
│── profiles.yml # Cấu hình kết nối tới Snowflake, BigQuery, Redshift, v.v.
│── packages.yml # Quản lý các package dbt (tương tự requirements.txt của Python)
├── models/ # Contains SQL files that define dbt models, which are SQL queries that transform raw data into the desired format.
│ ├── staging/ # Các bảng tạm (staging tables) trước khi chuyển đổi
│ ├── marts/ # Các bảng đầu ra (final data marts)
│ ├── intermediate/ # Các bảng trung gian (dùng cho transformation)
│ ├── sources.yml # Định nghĩa nguồn dữ liệu (source tables)
│ └── schema.yml # Định nghĩa schema, kiểm tra và tài liệu mô hình
├── snapshots/ # Contains SQL files that define dbt snapshots, which capture the state of a table at a specific point in time.
├── tests/ # Contains SQL files that define dbt tests, which are used to validate the data and ensure data quality.
├── macros/ # Contains SQL files that define dbt macros, which are reusable SQL snippets that can be used in models, tests, and other dbt files.
├── seeds/ # Contains CSV files that are used to seed data into the database, providing static data that can be referenced in models.
├── analysis/ # Contains SQL files for analysis purposes, allowing for ad-hoc queries and analysis outside of the main models.
├── logs/ # Contains log files generated by dbt operations, useful for debugging and tracking the execution of dbt commands.
│ └── dbt.log # Log file for dbt operations
└── target/ # Contains compiled files and artifacts generated by dbt, including the manifest file which contains metadata about the dbt project.
└── manifest.json # JSON file containing the dbt manifest
3.1.3. Configs & Properties#
3.1.3.1. Project configuration#
dbt_project.yml
: defines the directory of the dbt project and other project configurations.
YAML key |
Value description |
---|---|
Your project’s name in snake case |
|
Version of your project |
|
Restrict your project to only work with a range of dbt Core versions |
|
The profile dbt uses to connect to your data platform |
|
Directories to where your model and source files live |
|
Directories to where your seed files live |
|
Directories to where your test files live |
|
Directories to where your analyses live |
|
Directories to where your macros live |
|
Directories to where your snapshots live |
|
Directories to where your docs blocks live |
|
Project variables you want to use for data compilation |
For complete details on project configurations, see dbt_project.yml.
Chú ý sử dụng đúng naming convention: https://docs.getdbt.com/reference/dbt_project.yml#naming-convention
3.1.3.2. Models config #
Model configs có thể định nghĩa theo 3 cách: ^886e82
dbt_project.yml
: nơi tổng hợp config của project và từng resource files (top-level)properties.yml
: đặt trong từng resources để apply config cho resource đó (mid-level , ghi đè top-level)config()
block trong từng file.sql
(low-level, ghi đè mid-level và top-level)
Một số properties chỉ được cài đặt trong properties.yml
:
source
properties (e.g.loaded_at_field
,freshness
)exposure
properties (e.g.type
,maturity
)macro
properties (e.g.arguments
)
# models/jaffle_shop.yml
version: 2
sources:
- name: raw_jaffle_shop
description: A replica of the postgres database used to power the jaffle_shop app.
tables:
- name: customers
columns:
- name: id
description: Primary key of the table
tests:
- unique
- not_null
- name: orders
columns:
- name: id
description: Primary key of the table
tests:
- unique
- not_null
- name: user_id
description: Foreign key to customers
- name: status
tests:
- accepted_values:
values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
models:
- name: stg_jaffle_shop__customers
config:
tags: ['pii']
columns:
- name: customer_id
tests:
- unique
- not_null
- name: stg_jaffle_shop__orders
config:
materialized: view
columns:
- name: order_id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
config:
severity: warn
How to apply config on resource path: (follow the syntax)
3.1.3.3. General properties#
3.1.3.3.1. columns#
định nghĩa columns properties: data_type, description, quote, tests, tags, meta
version: 2
models:
- name: customers
description: "Thông tin về khách hàng"
columns:
- name: customer_id
description: "Mã định danh duy nhất của khách hàng"
data_type: "integer"
tests:
- not_null
- unique
- name: email
description: "Địa chỉ email của khách hàng"
data_type: "string"
tests:
- not_null
- unique
tags: ["PII"]
meta:
sensitivity: "high"
models customers
có hai cột customer_id
và email
, mỗi cột được mô tả chi tiết với các thuộc tính như description
, data_type
, tests
, tags
và meta
. Việc định nghĩa chi tiết này giúp cải thiện tài liệu hóa và đảm bảo chất lượng dữ liệu trong dự án dbt của bạn.
3.1.3.3.2. config#
3.1.3.3.3. constraints#
Các constraints (ràng buộc) trong dbt không chỉ đơn thuần là validation (kiểm tra dữ liệu) sau khi chạy model, mà chúng thực sự được áp dụng ở cấp độ cấu trúc bảng trên database.
constraints giúp bảo vệ tính toàn vẹn dữ liệu ngay từ đầu, trong khi
dbt test
giúp phát hiện dữ liệu sai nhưng không ngăn chặn. Nếu database của bạn hỗ trợ constraints, đây là một cách mạnh mẽ để kiểm soát chất lượng dữ liệu trực tiếp trong schema.
Cụ thể:
Khi bạn khai báo constraints trong model, dbt sẽ yêu cầu database áp dụng ràng buộc trên bảng (ví dụ: cột không được null, cột phải unique, có khóa chính/khóa ngoại, v.v.).
Nếu dữ liệu vi phạm constraints này, database sẽ chặn việc nhập dữ liệu vào bảng ngay từ đầu.
Điều này khác với việc chạy test trong dbt (ví dụ:
dbt test
), vì test chỉ kiểm tra sau khi dữ liệu đã được nạp vào.
3.1.3.3.4. deprecation_date#
3.1.3.3.5. description#
description
được sử dụng để cung cấp mô tả cho các resources như models, source, seed, snapshot, analyses, macro, test dữ liệu và các cột tương ứng của chúng. Những mô tả này giúp tài liệu hóa dự án và được hiển thị trên trang web tài liệu do dbt tạo ra.
3.1.3.3.6. lastest_version#
latest_version
được sử dụng để chỉ định phiên bản mới nhất của một mô hình đã được phiên bản hóa. Điều này đặc biệt hữu ích khi bạn có nhiều phiên bản của cùng một mô hình và muốn kiểm soát phiên bản nào sẽ được sử dụng mặc định trong các tham chiếu không chỉ định rõ ràng phiên bản.
models:
- name: ten_mo_hinh
latest_version: 2
versions:
- v: 3
- v: 2
- v: 1
Trong ví dụ trên, mặc dù có ba phiên bản (1
, 2
, 3
), nhưng latest_version
được đặt là 2
. Điều này có nghĩa là bất kỳ tham chiếu nào đến mô hình ten_mo_hinh
mà không chỉ định phiên bản cụ thể (ví dụ: ref('ten_mo_hinh')
) sẽ mặc định trỏ đến phiên bản 2
. Phiên bản 3
sẽ được coi là “prerelease” (phiên bản chuẩn bị phát hành), trong khi phiên bản 1
được coi là “old” (cũ).
Nếu không chỉ định latest_version
, dbt sẽ mặc định coi phiên bản 3
là phiên bản mới nhất. Do đó, ref('ten_mo_hinh')
sẽ trỏ đến ten_mo_hinh.v3
3.1.3.3.7. include-exclude columns#
3.1.3.3.8. Data tests#
tests
property defines assertions about a column, table, or view. 4 kiểm thử tích hợp sẵn trong dbt:
not_null
: Xác nhận rằng không có giá trịnull
trong một cột.unique
: Xác nhận rằng không có giá trị trùng lặp trong một cột.accepted_values
: Xác nhận rằng tất cả các giá trị trong một cột đều nằm trong một danh sách giá trị được cung cấp.relationships
: Xác nhận rằng tất cả các bản ghi trong bảng con có một bản ghi tương ứng trong bảng cha (tính toàn vẹn tham chiếu).
Ngoài ra còn có các custom tests.
3.1.3.3.9. versions#
versions
cho phép bạn quản lý và theo dõi các phiên bản khác nhau của một mô hình theo thời gian. Điều này đặc biệt hữu ích khi bạn cần thực hiện các thay đổi quan trọng đối với mô hình mà không muốn ảnh hưởng đến các quy trình hoặc người dùng hiện tại đang dựa vào phiên bản cũ.
# models/<schema>.yml
version: 2
models:
- name: model_name
versions:
- v: <version_identifier> # required
defined_in: <file_name> # optional -- default is <model_name>_v<v>
columns:
# specify all columns, or include/exclude columns from the top-level model YAML definition
- [include](/reference/resource-properties/include-exclude): <include_value>
[exclude](/reference/resource-properties/include-exclude): <exclude_list>
# specify additional columns
- name: <column_name> # required
- v: ...
# optional
[latest_version](/reference/resource-properties/latest_version): <version_identifier>
3.1.3.4. General configs#
Cấu hình |
Mục đích |
---|---|
Điều khiển việc hiển thị tài nguyên trong tài liệu tự động của dbt và đặt màu cho các nút. |
|
Xác định mức độ truy cập của mô hình ( |
|
Đặt tên thay thế cho bảng hoặc view được tạo trong cơ sở dữ liệu. |
|
Xác định hợp đồng cho mô hình, bao gồm các ràng buộc về schema và dữ liệu. |
|
Chỉ định cơ sở dữ liệu nơi tài nguyên sẽ được tạo. |
|
Bật hoặc tắt tài nguyên trong quá trình chạy dbt. |
|
Đánh dấu một cột là cột thời gian sự kiện, hữu ích cho các thao tác liên quan đến thời gian. |
|
Buộc làm mới hoàn toàn cho các mô hình gia tăng trong lần chạy tiếp theo. |
|
Áp dụng quyền truy cập cho các đối tượng cơ sở dữ liệu được tạo bởi dbt. |
|
Gán mô hình vào một nhóm để quản lý và tổ chức. |
|
Lưu trữ thông tin bổ sung tùy chỉnh cho tài nguyên. |
|
Lưu trữ mô tả tài nguyên dưới dạng nhận xét trong cơ sở dữ liệu. |
|
Thực thi các lệnh SQL hoặc macro trước và sau khi chạy một mô hình. |
|
Chỉ định schema nơi tài nguyên sẽ được tạo. |
|
Gắn thẻ cho tài nguyên để phân loại và lựa chọn trong các thao tác dbt. |
|
Xác định khóa duy nhất cho các mô hình gia tăng. |
3.1.4. Resources#
3.1.4.1. Models#
Models are the basic building block of your business logic
Materialized as tables, views, etc…
They live in SQL files in the
models
folderModels can reference each other and use templates and macros
Materializations types
Category |
View |
Table |
Incremental |
Ephemeral (CTEs) |
Materialized View |
---|---|---|---|---|---|
Pros |
- No additional data is stored. |
- Fast to query. |
- Significantly reduces build time by only transforming new records. |
- Allows reusable logic. |
- Combines query performance of a table with data freshness of a view. |
Cons |
- Slow for significant transformations or when stacked on top of other views. |
- Takes time to rebuild, especially for complex transformations. |
- Requires additional configuration and is more complex than other models. |
- Cannot be directly queried. |
- Fewer configuration options depending on the database platform. |
Advice |
- Start with views before switching to another materialization. |
- Use for models queried by BI tools for better user experience. |
- Best for event-style data. |
- Use for lightweight transformations early in the DAG. |
- Use when incremental models are sufficient, but you want the data platform to manage incremental logic and refresh. |
Use it when… |
- You want a lightweight representation. |
- You read from this model repeatedly. |
- Fact tables. |
- You merely want an alias to your data. |
- Similar use cases as incremental models but want the database to manage refresh. |
Don’t use it when… |
- You read from the same model several times. |
- Building single-use models. |
- You want to update historical records. |
- You read from the same model several times. |
- The database platform doesn’t support materialized views. |
Có thể config materializations trong 3 cách theo như [[#^886e82]]
Ví dụ trong dbt_project.yml
# dbt_project.yml
models:
dbtlearn:
+materialized: view
dim:
+materialized: table
hoặc trong config block
3.1.4.1.1. Table/View Models#
{{
config(
materialized = 'view'
)
}}
WITH src_hosts AS (
SELECT
*
FROM
{{ ref('src_hosts') }}
)
SELECT
host_id,
NVL(
host_name,
'Anonymous'
) AS host_name,
is_superhost,
created_at,
updated_at
FROM
src_hosts
3.1.4.1.2. Incremental Models#
The fct/fct_reviews.sql
model:
{{
config(
materialized = 'incremental',
on_schema_change='fail'
)
}}
WITH src_reviews AS (
SELECT * FROM {{ ref('src_reviews') }}
)
SELECT * FROM src_reviews
WHERE review_text is not null
{% if is_incremental() %}
AND review_date > (select max(review_date) from {{ this }})
{% endif %}
3.1.4.1.3. Ephemeral view#
+materialized: ephemeral
Mỗi 1 model dạng ephemeral sẽ được lưu thành query tạm (mà không tạo thành đối tượng trên database: table, view…)
3.1.4.2. Seeds#
Seeds là local files dùng để upload trực triếp lên data warehouse from DBT, được lưu trữ trong folder /seeds/
Các command run model project không tải lại các file seed lên warehouse, ta cần chạy lệnh
dbt seed
hoặcdbt build
để load các folder lên data warehouse
How to write Seed properties
#seeds/<filename>.yml
version: 2
seeds:
- name: <string>
description: <markdown_string>
docs:
show: true | false
node_color: <color_id>
config:
<seed_config>: <config_value>
tests:
- <test>
- ... # declare additional tests
columns:
- name: <column name>
description: <markdown_string>
meta: {<dictionary>}
quote: true | false
tags: [<string>]
tests:
- <test>
- ... # declare additional tests
- name: ... # declare properties of additional columns
- name: ... # declare properties of additional seeds
3.1.4.3. Sources#
Sources là những data layer trừu tượng đại diện cho input data (data từ các nguồn database, schema khác) mà không bị thay đổi trong quá trình build và run DBT, tuy nhiên vì nó là data ở dạng database nên giá trị sẽ có tính chất freshness (thay vì cố định như seeds local files)
Định nghĩa Sources in model/
, check các properties and config
# models/sources.yml
version: 2
sources:
- name: airbnb # Source name
schema: raw # Schema name
tables:
- name: listings # reference to the table name
identifier: raw_listings # Table name of data source
- name: hosts
identifier: raw_hosts
- name: reviews
identifier: raw_reviews
loaded_at_field: date # check mức độ freshness của trường 'date' với hiện tại, nếu date quá cũ sau hiện tại thì sẽ warning hoặc error
freshness:
warn_after: {count: 1, period: hour}
error_after: {count: 24, period: hour}
filter: datediff('day', date, current_timestamp) < 2 # optional
filter
sẽ thực hiện query filder bảng trước khi chạy assertions để tránh TH query cả bảng, nhằm tối ưu chi phí và performance.
3.1.4.4. Snapshots#
Strategy Snapshot được sử dụng để ghi lại sự thay đổi của dữ liệu theo thời gian bằng cách tạo bảng snapshot. Điều này rất hữu ích cho việc theo dõi các thay đổi trong dữ liệu quan trọng, chẳng hạn như thông tin khách hàng, trạng thái đơn hàng hoặc bất kỳ dữ liệu nào có thể thay đổi theo thời gian.
Snapshot sẽ tạo ra các bảng có cấu trúc gần giống như các bảng được snapshot, bổ sung thêm các trường
snapshot_id
,dbt_valid_from
,dbt_valid_to
. Khi bảng gốc được thay đổi và chạy commanddbt snapshot
sẽ update lại row bị thay đổi trong bảng gốc trong bảng snapshot tương ứng.
Có 2 strategies cho việc snapshot:
Timestamp Strategy (Chiến lược dựa trên dấu thời gian)
Cơ chế hoạt động: So sánh unique_key
customer_id
+ một cột dấu thời gian (updated_at
,modified_date
, v.v.) để xác định khi nào bản ghi đã thay đổi.Nếu giá trị trong cột này thay đổi, DBT sẽ tạo một bản ghi snapshot mới.
Phù hợp với: Các bảng có một cột timestamp đại diện cho lần cập nhật gần nhất.
snapshot customer_snapshot {
target_database: my_database
target_schema: snapshots
unique_key: customer_id
strategy: timestamp
updated_at: updated_at
}
```
Ưu điểm:
Hiệu suất cao vì chỉ cần kiểm tra một cột timestamp.
Dễ triển khai nếu dữ liệu có cột timestamp đáng tin cậy.
Nhược điểm:
Không thể theo dõi các thay đổi nếu dữ liệu không có cột
updated_at
.Nếu timestamp không được cập nhật đúng cách, có thể bỏ lỡ thay đổi.
Check Strategy (Chiến lược kiểm tra toàn bộ hàng)
Cơ chế hoạt động: So sánh toàn bộ giá trị của một hoặc nhiều cột để phát hiện thay đổi.
Nếu bất kỳ giá trị nào trong danh sách cột được kiểm tra thay đổi, DBT sẽ tạo một snapshot mới.
Phù hợp với: Các bảng không có cột
updated_at
hoặc khi bạn muốn theo dõi sự thay đổi của một tập hợp cột cụ thể.
snapshot order_snapshot {
target_database: my_database
target_schema: snapshots
unique_key: order_id
strategy: check
check_cols: ['status', 'total_price', 'customer_id']
}
Ưu điểm:
Linh hoạt hơn vì không phụ thuộc vào cột timestamp.
Có thể theo dõi nhiều thay đổi cùng lúc.
Nhược điểm:
Tốn tài nguyên hơn vì phải so sánh toàn bộ dữ liệu trong các cột chỉ định.
Cần chọn các cột kiểm tra phù hợp, nếu không có thể tạo quá nhiều snapshot không cần thiết.
So sánh Timestamp vs Check Strategy
Tiêu chí |
Timestamp Strategy |
Check Strategy |
---|---|---|
Cơ chế |
Dựa vào cột timestamp |
So sánh nhiều cột chỉ định |
Hiệu suất |
Cao hơn do chỉ kiểm tra một cột |
Chậm hơn nếu nhiều cột được kiểm tra |
Dễ triển khai |
Dễ nếu có cột timestamp |
Phức tạp hơn |
Độ chính xác |
Phụ thuộc vào độ tin cậy của timestamp |
Chính xác hơn nếu chọn đúng cột |
Khi nào nên sử dụng từng loại? |
Dùng
timestamp strategy
nếu bảng dữ liệu có cộtupdated_at
hoặc dấu thời gian đáng tin cậy.Dùng
check strategy
nếu cần theo dõi sự thay đổi của nhiều cột hoặc không có cột timestamp.
Cấu trúc file snapshot
-- `snapshots/scd_raw_listings.sql`
-- snapshot begining block
{% snapshot scd_raw_listings %}
-- define how to snapshot by snapshots config
{{
config(
target_schema='DEV',
unique_key='id',
strategy='timestamp',
updated_at='updated_at',
hard_delete="invalidate"
)
}}
-- define what is snapshoted ?
select * FROM {{ source('airbnb', 'listings') }}
-- snapshot ending block
{% endsnapshot %}
3.1.4.4.1. snapshot properties#
hard_deletes
: action cho record trong bảng snapshot khi record đó bị delete khỏi bảng nguồn
3.1.4.5. Tests#
tests là các kiểm thử dữ liệu giúp đảm bảo tính toàn vẹn và chính xác của dữ liệu trong mô hình. Khi chạy lệnh dbt test
, dbt sẽ thực thi các kiểm thử đã định nghĩa để xác nhận rằng dữ liệu đáp ứng các quy tắc và ràng buộc đã đặt ra.
dbt hỗ trợ hai loại kiểm thử chính là Generic Tests và Singular Tests
🔹 Chạy test:
dbt test
: chạy toàn bộ các testsdbt test --select customers
: chỉ chạy test cho một mô hình cụ thể (customer
)
🔹 Kết quả:
Nếu test thành công: Hiển thị ✅ PASSED.
Nếu test thất bại: Hiển thị ❌ FAILED với số dòng không đạt yêu cầu.
3.1.4.5.1. Generic Tests (Kiểm thử chung)#
Là các kiểm thử có thể áp dụng cho nhiều mô hình hoặc cột khác nhau.
Được tích hợp sẵn trong dbt hoặc từ các package mở rộng như
dbt_utils
.
Test Name |
Mô tả |
---|---|
|
Đảm bảo cột có giá trị duy nhất (không trùng lặp). |
|
Đảm bảo cột không chứa giá trị NULL. |
|
Đảm bảo giá trị của cột nằm trong danh sách cho phép. |
|
Đảm bảo giá trị của cột nằm trong danh sách giá trị cột khác |
Sử dụng các macro custom function để test |
|
Sử dụng các dbt packages để thêm function test |
|
Cách sử dụng: Generic tests được khai báo trực tiếp trong tệp models/schema.yml. |
# models/schema.yml
version: 2
models:
- name: dim_listings_cleansed
description: Cleansed table which contains Airbnb listings.
columns:
- name: listing_id
description: Primary key for the listing
tests:
- unique
- not_null
- name: host_id
description: The hosts's id. References the host table.
tests:
- not_null
- relationships:
to: ref('dim_hosts_cleansed')
field: host_id # reference field 'host_id' in `dim_hosts_cleansed`
- name: room_type
description: Type of the apartment / room
tests:
- accepted_values:
values: ['Entire home/apt',
'Private room',
'Shared room',
'Hotel room']
- name: minimum_nights
description: '{{ doc("dim_listing_cleansed__minimum_nights") }}'
tests:
- positive_value # use macro function
- name: dim_hosts_cleansed
description: Cleansed table for the Airbnb hosts
columns:
- name: host_id
description: The id of the host. This is the primary key.
tests:
- not_null
- unique
- name: host_name
description: The name of the host
tests:
- not_null
- name: is_superhost
description: Defines whether the hosts is a superhost.
tests:
- accepted_values:
values: ['t', 'f']
- name: dim_listings_w_hosts
tests:
- dbt_expectations.expect_table_row_count_to_equal_other_table: # use package "dbt_expectations"
compare_model: source('airbnb', 'listings')
columns:
- name: price
tests:
- dbt_expectations.expect_column_values_to_be_of_type:
column_type: number
- dbt_expectations.expect_column_quantile_values_to_be_between:
quantile: .99
min_value: 50
max_value: 500
- dbt_expectations.expect_column_max_to_be_between:
max_value: 5000
config:
severity: warn
- name: fct_reviews
columns:
- name: listing_id
tests:
- relationships:
to: ref('dim_listings_cleansed')
field: listing_id
- name: reviewer_name
tests:
- not_null
- name: review_sentiment
tests:
- accepted_values:
values: ['positive', 'neutral', 'negative']
💡 Khi chạy dbt test
, dbt sẽ tự động tạo và chạy các truy vấn SQL để kiểm tra điều kiện trên.
3.1.4.5.2. Singular Tests (Kiểm thử tùy chỉnh)#
Là các kiểm thử được viết dưới dạng truy vấn SQL.
Kiểm thử này có thể kiểm tra các quy tắc phức tạp, chẳng hạn như điều kiện logic hoặc dữ liệu bất thường.
Được khai báo trong thư mục
tests/
dưới dạng file SQL.
Cách sử dụng: Tạo tệp tests/dim_listings_minimun_nights.sql
:
# tests/dim_listings_minimun_nights.sql
SELECT
*
FROM
{{ ref('dim_listings_cleansed') }}
WHERE minimum_nights < 1
LIMIT 10
Thực hiện test: dbt test --select dim_listings_cleansed
💡 Nếu truy vấn trả về bất kỳ dòng nào, test sẽ thất bại.
3.1.4.5.3. Mở rộng tests với dbt-utils#
Dbt hỗ trợ thêm các kiểm thử nâng cao từ package dbt-utils
, giúp kiểm thử linh hoạt hơn.
Trong file packages.yml
:
packages:
- package: dbt-labs/dbt_utils
version: 1.3.0 # version
Ví dụ: Kiểm tra trường email
có đúng định dạng không?
models:
- name: customers
columns:
- name: email
tests:
- dbt_utils.expression_is_true:
expression: "email LIKE '%@%.%'"
🔹 Nếu có email không đúng định dạng, test sẽ thất bại.
3.1.4.5.4. Check SQL to get fail test#
Nếu trong TH chạy test bị lỗi, thông báo sẽ chỉ ra file .sql
chạy test bị fail. Để check file .sql
đó:
For Mac/Linux
cat <filepath>
For Windows:
type <filepath>
3.1.4.6. Macros#
🔹Macro trong dbt là các đoạn mã SQL được viết bằng Jinja có thể tái sử dụng, tương tự như hàm (function) trong lập trình. Macro giúp:
Tránh lặp lại code.
Viết SQL động có thể thay đổi tùy theo tham số.
Dễ dàng tùy chỉnh logic xử lý dữ liệu.
Giúp duy trì code sạch và dễ bảo trì.
🔹Macros được lưu trong thư mục macros/
của dự án dbt. Khi dbt chạy, nó sẽ biên dịch macro thành SQL thực thi.
🔹Macros có thể chứa:
Biến (
{{ variable }}
) để chèn giá trị động.Logic điều kiện (
if-else
) để tùy chỉnh SQL.Vòng lặp (
for loop
) để lặp qua danh sách giá trị.
3.1.4.6.1. Cấu trúc Macro và cách sử dụng#
-- macros/<filename.sql>
{% macro macro_name(param1, param2) %}
-- Logic SQL của macro
{% endmacro %}
🔹For Loop + Sử dụng trong singular tests :
-- macros/no_nulls_in_columns.sql
{% macro no_nulls_in_columns(model) %}
SELECT * FROM {{ model }} WHERE
{% for col in adapter.get_columns_in_relation(model) -%}
{{ col.column }} IS NULL OR
{% endfor %}
FALSE
{% endmacro %}
Sử dụng trong singular test
-- tests/no_nulls_in_dim_listings.sql
{{ no_nulls_in_columns(ref('dim_listings_cleansed')) }}
🔹SQL Select Template + Sử dụng trong generic tests:
-- macros/positive_value.sql
{% test positive_value(model, column_name) %}
SELECT
*
FROM
{{ model }}
WHERE
{{ column_name}} < 1
{% endtest %}
Sử dụng trong generic tests:
# models/schema.yml
models:
- name: dim_listings_cleansed
columns:
- name: minimum_nights
tests:
- positive_value # use macro function
🔹SQL Function Template + Sử dụng trong models definition:
{% macro cents_to_dollars(column_name, scale=2) %}
({{ column_name }} / 100)::numeric(16, {{ scale }})
{% endmacro %}
🔹Dùng if-else
trong macro
{% macro check_table(table_name) %}
{% if execute %} -- Chỉ chạy trong dbt run, không chạy khi compile
SELECT COUNT(*) FROM {{ ref(table_name) }};
{% else %} -- chạy nếu chạy dbt compile
SELECT 'Skipping execution';
{% endif %}
{% endmacro %}
-- Sử dụng: {{ check_table('customers') }}
🔹Dùng for loop
trong macro
{% macro generate_columns(columns) %}
{% for col in columns %}
{{ col }} AS transformed_{{ col }},
{% endfor %}
{% endmacro %}
-- Sử dụng:
SELECT
{{ generate_columns(['sales', 'profit', 'revenue']) }}
FROM financial_data;
-- Sau khi compile:
SELECT
sales AS transformed_sales,
profit AS transformed_profit,
revenue AS transformed_revenue
FROM financial_data;
🔹Get biến môi trường (Environment Variables)
{% macro get_env_var(var_name, default='') %}
{% if var(var_name) %}
{{ var(var_name) }}
{% else %}
{{ default }}
{% endif %}
{% endmacro %}
-- Sử dụng:
SELECT {{ get_env_var('database_name', 'default_db') }} AS active_db;
3.1.4.6.2. Macro properties#
Macro properties được định nghĩa trong file properties.yml
(nên để trong folder macro/
) dùng để miêu tả function và các arguments liên quan:
3.1.4.7. Packages#
Packages DBT được list tại https://hub.getdbt.com/:
dbt_utils: bổ sung nhiều macro có thể (re)used across dbt projects
dbt_expectations: tích hợp nhiều macro test thay vì phải tự build hoặc test bên ngoài DBT
…
Cài thêm package
The contents of packages.yml
:
packages:
- package: dbt-labs/dbt_utils
version: 1.3.0
Chạy lệnh để load package: dbt deps
Sử dụng package
Sử dụng trong models
-- models/fct_reviews.sql
{{
config(
materialized = 'incremental',
on_schema_change='fail'
)
}}
WITH src_reviews AS (
SELECT * FROM {{ ref('src_reviews') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['listing_id', 'review_date', 'reviewer_name', 'review_text']) }}
AS review_id,
*
FROM src_reviews
WHERE review_text is not null
{% if is_incremental() %}
AND review_date > (select max(review_date) from {{ this }})
{% endif %}
3.1.4.8. Documentation#
Định nghĩa mô tả các models và field
The models/schema.yml
after adding the documentation:
version: 2
models:
- name: dim_listings_cleansed
description: Cleansed table which contains Airbnb listings.
columns:
- name: listing_id
description: Primary key for the listing
tests:
- unique
- not_null
- name: host_id
description: The hosts's id. References the host table.
tests:
- not_null
- relationships:
to: ref('dim_hosts_cleansed')
field: host_id
- name: room_type
description: Type of the apartment / room
tests:
- accepted_values:
values: ['Entire home/apt', 'Private room', 'Shared room', 'Hotel room']
- name: minimum_nights
description: '{{ doc("dim_listing_cleansed__minimum_nights") }}'
tests:
- positive_value
- name: dim_hosts_cleansed
columns:
- name: host_id
tests:
- not_null
- unique
- name: host_name
tests:
- not_null
- name: is_superhost
tests:
- accepted_values:
values: ['t', 'f']
- name: fct_reviews
columns:
- name: listing_id
tests:
- relationships:
to: ref('dim_listings_cleansed')
field: listing_id
- name: reviewer_name
tests:
- not_null
- name: review_sentiment
tests:
- accepted_values:
values: ['positive', 'neutral', 'negative']
Định nghĩa tham chiếu trong file markdown
The contents of models/docs.md
:
{% docs dim_listing_cleansed__minimum_nights %}
Minimum number of nights required to rent this property.
Keep in mind that old listings might have `minimum_nights` set
to 0 in the source tables. Our cleansing algorithm updates this to `1`.
{% enddocs %}
Định nghĩa tham chiếu trong file markdown chứa special assets
The contents of models/overview.md
:
{% docs __overview__ %}
# Airbnb pipeline
Hey, welcome to our Airbnb pipeline documentation!
Here is the schema of our input data:

{% enddocs %}
Tips: Có thể sử dụng VSCode Extension Power User for dbt để sửa documantation cho nhanh
3.1.4.8.1. Build Documentation#
dbt docs generate
: build documantationdbt docs serve
: chạy website hiện metadata của project và DAG Linage Graph
3.1.4.9. Analyses#
Folder analyses/
được dùng để chứa SQL ad-hoc queries, report, hoặc phân tích dữ liệu mà không cần phải materialize (tạo bảng hoặc view) như các mô hình (models/
).
Viết và lưu trữ câu truy vấn SQL mà bạn có thể chạy khi cần.
Phân tích dữ liệu mà không làm ảnh hưởng đến mô hình chính.
Chia sẻ truy vấn phức tạp giữa các thành viên trong nhóm.
The contents of analyses/full_moon_no_sleep.sql
:
WITH fullmoon_reviews AS (
SELECT * FROM {{ ref('fullmoon_reviews') }}
)
SELECT
is_full_moon,
review_sentiment,
COUNT(*) as reviews
FROM
fullmoon_reviews
GROUP BY
is_full_moon,
review_sentiment
ORDER BY
is_full_moon,
review_sentiment
Sau khi viết xong file SQL query, chạy phân tích bằng dbt compile
và check SQL sau khi compile bằng
For Mac:
cat target/compiled/{project_name}/<filepath>.sql
Window:
type target/compiled/{project_name}/<filepath>.sql
3.1.4.10. Hooks#
Hooks là SQLs được chạy tự động trước hoặc sau một sự kiện cụ thể, giúp kiểm soát và tối ưu quá trình ETL.
Hook Type |
Chạy Khi Nào? |
Ví Dụ |
---|---|---|
|
Trước khi chạy một model (model/seed/snapshot) |
Xóa dữ liệu cũ |
|
Sau khi chạy một model (model/seed/snapshot) |
Ghi log, kiểm tra dữ liệu |
|
Khi bắt đầu |
Ghi log toàn bộ pipeline |
|
Khi kết thúc |
Cập nhật trạng thái pipeline |
3.1.4.10.1. pre-hook
và post-hook
cho model#
Được sử dụng để chạy SQL trước (pre-hook
) hoặc sau (post-hook
) khi chạy một model.
Ví dụ 1: Audit logs trước khi chạy model
-- models/orders.sql
{{ config(
materialized='table',
pre_hook="INSERT INTO audit_logs (table_name, action, timestamp) VALUES ('orders', 'start', current_timestamp)",
post_hook="INSERT INTO audit_logs (table_name, action, timestamp) VALUES ('orders', 'end', current_timestamp)"
) }}
SELECT * FROM raw_data.orders;
📌 Khi chạy dbt run
, dbt sẽ:
Chạy
pre_hook
: Thêm log vàoaudit_logs
trước khi chạy model.Chạy model
orders.sql
.Chạy
post_hook
: Thêm log vàoaudit_logs
sau khi model chạy xong.
Ví dụ 2: Xóa dữ liệu cũ trước khi load
{{ config(
materialized='incremental',
pre_hook="DELETE FROM analytics.orders WHERE order_date >= '2024-01-01'"
) }}
SELECT * FROM raw_data.orders WHERE order_date >= '2024-01-01';
📌 Giúp tránh trùng dữ liệu khi load bảng mới.
Ví dụ 3: Thêm trực tiếp vào dbt_project.yml
để thực hiện cho tất cả các models trong configs
# dbt_project.yml
+post-hook:
- "GRANT SELECT ON {{ this }} TO ROLE REPORTER"
3.1.4.10.2. on-run-start
và on-run-end
(Chạy đầu/cuối dự án)#
Các hooks này chạy trước hoặc sau toàn bộ pipeline dbt run
, thay vì chỉ chạy cho từng model.
Ví dụ 4: Ghi log vào bảng run_logs
khi bắt đầu và kết thúc pipeline
Trong file dbt_project.yml
:
on-run-start:
- "INSERT INTO run_logs (run_id, status, start_time) VALUES ('{{ invocation_id }}', 'started', current_timestamp)"
on-run-end:
- "UPDATE run_logs SET status='completed', end_time=current_timestamp WHERE run_id='{{ invocation_id }}'"
📌 Mục đích:
on-run-start
: Ghi lại ID của lần chạy vàorun_logs
trước khi chạy models.on-run-end
: Cập nhật trạng thái khi quá trình chạy kết thúc.
3.1.4.10.3. Khi nào nên dùng Hooks?#
✅ Audit Logging: Ghi log trước/sau khi chạy models.
✅ Data Cleanup: Xóa dữ liệu cũ trước khi chạy (pre-hook
).
✅ Data Quality Checks: Chạy dbt test
tự động trước khi chạy models.
✅ Session Configuration: Set biến môi trường (SET TIME ZONE 'UTC'
).
✅ Incremental Loads: Xóa dữ liệu trùng (DELETE FROM table WHERE ...
).
3.1.4.10.4. Lưu ý khi sử dụng Hooks#
⚠ Hooks chạy trong transaction của dbt, nên nếu model fail, post-hook
có thể không chạy.
⚠ Không lạm dụng hooks vì có thể gây phức tạp cho pipeline.
⚠ Chạy SQL nặng trong post-hook
có thể ảnh hưởng hiệu suất.
3.1.4.11. Exposures (Dashboard)#
Exposures trong dbt là cách để theo dõi và quản lý những hệ thống, báo cáo, hoặc ứng dụng sử dụng dữ liệu từ dbt. Nó giúp bạn hiểu ai đang sử dụng dữ liệu được tạo bởi dbt, từ đó giúp dễ dàng kiểm soát và đánh giá tác động khi thay đổi dữ liệu.
Mục tiêu:
🔹 Quản lý tài nguyên phụ thuộc: Biết được dashboard, ML model, hoặc hệ thống nào đang dùng dữ liệu.
🔹 Cải thiện tài liệu (dbt docs
): Hiển thị các ứng dụng sử dụng dbt models trong dbt docs.
🔹 Hỗ trợ lineage (dbt deps
): Xác định nếu có thay đổi trong models ảnh hưởng đến báo cáo nào.
🔹 Tăng khả năng truy xuất nguồn gốc dữ liệu: Biết ai đang tiêu thụ dữ liệu dbt.
3.1.4.11.1. Config Exposure#
Tạo file exposures.yml
(hoặc bất kỳ tên gì) trong thư mục models/
hoặc exposures/
:
Template
# models/<filename>.yml
version: 2
exposures:
- name: <string_with_underscores>
[description](https://docs.getdbt.com/reference/resource-properties/description): <markdown_string>
type: {dashboard, notebook, analysis, ml, application}
url: <string>
maturity: {high, medium, low} # Indicates level of confidence or stability in the exposure
[tags](https://docs.getdbt.com/reference/resource-configs/tags): [<string>]
[meta](https://docs.getdbt.com/reference/resource-configs/meta): {<dictionary>}
owner:
name: <string>
email: <string>
depends_on:
- ref('model')
- ref('seed')
- source('name', 'table')
- metric('metric_name')
label: "Human-Friendly Name for this Exposure!"
[config](https://docs.getdbt.com/reference/resource-properties/config):
enabled: true | false
- name: ... # declare properties of additional exposures
# models/dashboard.yml
version: 2
exposures:
- name: executive_dashboard
label: Executive Dashboard
type: dashboard
maturity: low
url: https://00d200da.us1a.app.preset.io/superset/dashboard/x/?edit=true&native_filters_key=fnn_HJZ0z42ZJtoX06x7gRbd9oBFgFLbnPlCW2o_aiBeZJi3bZuyfQuXE96xfgB
description: Executive Dashboard about Airbnb listings and hosts
depends_on:
- ref('dim_listings_w_hosts')
- ref('mart_fullmoon_reviews')
owner:
name: Zoltan C. Toth
email: dbtstudent@gmail.com
Thuộc tính |
Ý nghĩa |
---|---|
|
Tên duy nhất của exposure (không có dấu cách). |
|
Loại hệ thống sử dụng dữ liệu (dashboard, ML, application, analysis, etc.). |
|
Tên dễ đọc của exposure (hiển thị trong dbt docs). |
|
Mô tả về hệ thống hoặc báo cáo đang dùng dữ liệu. |
|
Danh sách models dbt hoặc sources mà hệ thống này phụ thuộc vào. |
|
Người chịu trách nhiệm cho hệ thống này (thường là team hoặc user cụ thể). |
Các loại Exposures phổ biến
Loại ( |
Ý nghĩa |
---|---|
|
Các bảng điều khiển (Looker, Tableau, Power BI, etc.). |
|
Mô hình Machine Learning sử dụng dữ liệu từ dbt. |
|
Ứng dụng tiêu thụ dữ liệu từ dbt. |
|
Báo cáo hoặc nghiên cứu dùng dữ liệu từ dbt. |
3.1.4.11.2. Hiển thị Exposures trong dbt docs#
Chạy lệnh sau để tạo tài liệu:
dbt docs generate
dbt docs serve
Sau đó, mở trình duyệt và xem lineage của exposures trong dbt UI.
3.1.4.11.3. Kiểm tra dependencies của một Exposure#
dbt ls --select exposure:sales_dashboard+
📌 Mục đích: Hiển thị toàn bộ models mà sales_dashboard
phụ thuộc vào.
3.1.4.12. Variables#
Variables (vars
) trong dbt là các biến có thể được truyền vào dbt để sử dụng trong models, macros, hoặc tests. Chúng giúp tùy chỉnh tham số, giúp dbt linh hoạt hơn mà không cần sửa đổi SQL code trực tiếp.
3.1.4.12.1. Cách thiết lập vars
trong dbt#
Có 3 cách chính để thiết lập biến (vars
):
3.1.4.12.1.1. Định nghĩa trong dbt_project.yml
#
Bạn có thể khai báo biến trực tiếp trong file dbt_project.yml
:
# dbt_project.yml
vars:
country: "USA"
start_date: "2024-01-01"
max_orders: 1000
📌 Biến này sẽ có giá trị mặc định và có thể ghi đè khi chạy dbt.
3.1.4.12.1.2. Truyền vars
khi chạy dbt run
#
Bạn có thể truyền biến khi chạy lệnh dbt:
dbt run --vars '{"country": "Canada", "start_date": "2024-02-01"}'
📌 Giá trị của biến sẽ thay thế giá trị trong dbt_project.yml
chỉ trong lần chạy đó.
3.1.4.12.1.3. Định nghĩa vars
trong một model cụ thể#
Bạn có thể đặt vars
chỉ cho một model trong config
:
{{ config(
materialized='table',
vars={"country": "UK"}
) }}
SELECT *
FROM customers
WHERE country = '{{ var("country", "USA") }}'
📌 Nếu biến country
không được đặt, nó sẽ mặc định là "USA"
.
3.1.4.12.2. Cách sử dụng vars
trong dbt#
3.1.4.12.2.1. SQL models#
Trong file models/customers.sql
, bạn có thể sử dụng vars
để lọc dữ liệu:
SELECT *
FROM customers
WHERE country = '{{ var("country", "USA") }}'
📌 Nếu chạy: dbt run --vars '{"country": "Canada"}'
→ Query sẽ chỉ lấy khách hàng ở Canada
.
3.1.4.12.2.2. macros#
Biến cũng có thể dùng trong macros (Jinja):
{% macro filter_by_country() %}
country = '{{ var("country", "USA") }}'
{% endmacro %}
Sau đó có thể dùng macro này trong model:
SELECT *
FROM customers
WHERE {{ filter_by_country() }}
3.1.4.12.2.3. seeds#
Nếu bạn có seed CSV, bạn có thể dùng vars
để giới hạn dữ liệu:
seeds:
my_project:
my_seed_file:
vars:
start_date: "2024-01-01"
Sau đó, trong SQL:
SELECT *
FROM {{ ref('my_seed_file') }}
WHERE order_date >= '{{ var("start_date", "2023-01-01") }}'
📌 Khi chạy dbt seed
, dữ liệu sẽ được lọc theo start_date
.
3.1.4.12.2.4. tests#
Bạn có thể tham chiếu vars
khi viết test tùy chỉnh:
tests:
- name: test_minimum_orders
description: "Check if number of orders is greater than threshold"
sql: >
SELECT COUNT(*)
FROM {{ ref('orders') }}
WHERE total_orders < {{ var("max_orders", 500) }}
📌 Giá trị max_orders
có thể thay đổi khi chạy dbt.
3.1.5. DBT Command#
Command |
Description |
---|---|
Initializes a new dbt project |
|
Debugs dbt connections and projects |
|
Builds and tests all selected resources (models, seeds, snapshots, tests), this will do: run models, test tests, snapshot snapshots, seed seeds |
|
Runs the models in a project follow DAG order |
|
Executes tests defined (models, sources, snapshots, seeds) in a project |
|
Loads CSV files into the database |
|
Executes “snapshot” jobs defined in a project |
|
Generates documentation for a project |
|
Invokes a macro, including running arbitrary maintenance SQL against the database |
|
Deletes artifacts present (folder: |
|
Clones selected models from the specified state |
|
Compiles (but does not run) the models in a project |
|
Downloads dependencies for a project |
|
Enables users to debug long-running sessions by interacting with active invocations. |
|
Lists resources defined in a dbt project |
|
Parses a project and writes detailed timing info |
|
Retry the last run |
|
Previews table rows post-transformation |
|
Provides tools for working with source data (including validating that sources are “fresh”) |
3.1.6. Test & debug DBT#
The original Great Expectations project on GitHub: great-expectations/great_expectations
dbt-expectations: calogica/dbt-expectations
For the final code in packages.yml, models/schema.yml and models/sources.yml, please refer to the course’s Github repo: nordquant/complete-dbt-bootcamp-zero-to-hero
Testing a single model:
dbt test --select dim_listings_w_hosts
Testing individual sources:
dbt test --select source:airbnb.listings
Debugging dbt:
dbt --debug test --select dim_listings_w_hosts
Logging:
The contents of macros/logging.sql
:
{% macro learn_logging() %}
{{ log("Call your mom!") }}
{{ log("Call your dad!", info=True) }} --> Logs to the screen, too
-- {{ log("Call your dad!", info=True) }} --> This will be put to the screen
{# log("Call your dad!", info=True) #} --> This won't be executed
{% endmacro %}
Executing the macro:
dbt run-operation learn_logging
3.1.7. Deployment#
3.1.8. Orchestration#
Links to different orchestrators
3.1.8.1. Dagster#
Set up your environment
Let’s create a virtualenv and install dbt and dagster. These packages are located in [requirements.txt].
virutalenv venv -p python3.11
pip install -r requirements.txt
Create a dagster project
Dagster has a command for creating a dagster project from an existing dbt project:
dagster-dbt project scaffold --project-name dbt_dagster_project --dbt-project-dir=dbtlearn
At this point in the course, open schedules.py and uncomment the schedule logic.
Start dagster Now that our project is created, start the Dagster server:
On Windows - PowerShell (Like the VSCode Terminal Window)
cd dbt_dagster_project
$env:DAGSTER_DBT_PARSE_PROJECT_ON_LOAD = 1
dagster dev
On Windows (Using cmd)
cd dbt_dagster_project
setx DAGSTER_DBT_PARSE_PROJECT_ON_LOAD 1
dagster dev
On Linux / Mac
cd dbt_dagster_project
DAGSTER_DBT_PARSE_PROJECT_ON_LOAD=1 dagster dev
We will continue our work on the dagster UI at http://localhost:3000/
Making incremental models compatible with orchestrators:
The updated contents of models/fct/fct_reviews.sql
:
{{
config(
materialized = 'incremental',
on_schema_change='fail'
)
}}
WITH src_reviews AS (
SELECT * FROM {{ ref('src_reviews') }}
)
SELECT
{{ dbt_utils.generate_surrogate_key(['listing_id', 'review_date', 'reviewer_name', 'review_text']) }} as review_id,
*
FROM src_reviews
WHERE review_text is not null
{% if is_incremental() %}
{% if var("start_date", False) and var("end_date", False) %}
{{ log('Loading ' ~ this ~ ' incrementally (start_date: ' ~ var("start_date") ~ ', end_date: ' ~ var("end_date") ~ ')', info=True) }}
AND review_date >= '{{ var("start_date") }}'
AND review_date < '{{ var("end_date") }}'
{% else %}
AND review_date > (select max(review_date) from {{ this }})
{{ log('Loading ' ~ this ~ ' incrementally (all missing dates)', info=True)}}
{% endif %}
{% endif %}
Passing a time range to our incremental model:
dbt run --select fct_reviews --vars '{start_date: "2024-02-15 00:00:00", end_date: "2024-03-15 23:59:59"}'
Reference - Working with incremental strategies: https://docs.getdbt.com/docs/build/incremental-models#about-incremental_strategy