dbt — analytics engineering
এই পাঠে যা শিখবেন
- "Analytics engineer" role — dbt কেন এটি জন্ম দিল
- Model, ref, source — তিন core concept
- Materialization choice — কোনটি কখন
- Tests, snapshots, documentation — production-grade analytics
১ · Analytics engineer — নতুন একটি role
২০২০-র আগে dataworld-এ দু'টি প্রধান role: data engineer (pipeline বানায়, Python/Spark) ও data analyst (BI dashboard, SQL). মাঝে একটি gap — কে warehouse-এ SQL transformation বানাবে?
dbtdbt (data Build Tool)২০১৬-তে Fishtown Analytics (এখন dbt Labs)-এ Tristan Handy তৈরি। Open-source dbt Core + paid dbt Cloud. আজকের modern data stack-এর কেন্দ্রীয় উপাদান। এই gap পূরণ করেছে — এবং একটি নতুন role জন্ম দিয়েছে: analytics engineer. SQL জানে, software engineering practice (Git, test, CI/CD) জানে, business context বোঝে।
১) SELECT-only: কোনো INSERT/UPDATE/DELETE নয়। dbt-ই DDL handle করে।
২) Modular: ছোট ছোট model — একটিতে এক transformation.
৩) Testable: প্রতিটি model-এ assertion (unique, not-null, relationship).
৪) Documented: YAML-এ description; auto-generated docs site.
২ · একটি dbt model দেখা যাক
Daraz-এর order data থেকে customer summary বানাচ্ছি — তিন stage-এ:
{{ config(materialized='view') }}
-- Source থেকে clean staging layer
select
order_id,
customer_id,
cast(order_date as date) as order_date,
cast(amount as numeric(18, 2)) as amount_bdt,
lower(trim(status)) as status
from {{ source('raw', 'orders') }}
where order_date is not null
SELECT. dbt run করলে warehouse-এ stg_orders নামে view তৈরি। {{ source('raw', 'orders') }} = Jinja templating, dbt resolve করে actual table name-এ।
৩ · ref() — dbt-এর সবচেয়ে গুরুত্বপূর্ণ function
একটি model অন্য model-এ depend করে। কিন্তু hard-code table name লেখা ভঙ্গুর — dev/prod-এ আলাদা schema, naming convention বদলায়।
{{ ref('model_name') }} — এই magic function দু'টি কাজ করে:
- Model name → actual fully-qualified table name resolve.
- Dependency graph (DAG) auto-build. dbt জানে কোনটা আগে run.
{{ config(materialized='table') }}
-- প্রতিটি customer-এর LTV summary
with orders as (
select * from {{ ref('stg_orders') }}
where status = 'completed'
)
select
customer_id,
count(*) as order_count,
sum(amount_bdt) as lifetime_value_bdt,
avg(amount_bdt) as avg_order_value,
min(order_date) as first_order,
max(order_date) as last_order,
current_date - max(order_date) as days_since_last_order
from orders
group by customer_id
{{ ref('stg_orders') }} দেখে dbt বুঝবে — customer_summary stg_orders-এর উপর depend. তাই dbt run করলে — আগে stg_orders, পরে customer_summary.
৪ · Materialization — চারটি option
একই SELECT কিন্তু dbt warehouse-এ চার ভিন্ন রকম materialize করতে পারে:
-
view: warehouse-এ
CREATE VIEW. Storage cost নেই, কিন্তু query-time-এ run. ছোট, frequently changing data-তে। -
table:
CREATE TABLE AS SELECT. প্রতি dbt run-এ পুরো rebuild. Read fast, কিন্তু rebuild expensive. - incremental: প্রথমবার full table; পরে শুধু new/changed row append. বড় fact table-এর জন্য আদর্শ।
- ephemeral: CTE হিসেবে inline. কোনো object তৈরি হয় না। Helper কাজে।
Incremental example:
{{ config(
materialized='incremental',
unique_key='transaction_id',
on_schema_change='append_new_columns'
) }}
select
transaction_id,
user_id,
amount,
transaction_at,
-- bKash style: derived columns
case when amount > 50000 then 'high' else 'normal' end as size_bucket
from {{ ref('stg_transactions') }}
{% if is_incremental() %}
-- শুধু last run-এর পর-এর data
where transaction_at >= (
select coalesce(max(transaction_at), '1900-01-01')
from {{ this }}
)
{% endif %}
{% if is_incremental() %} — Jinja template. প্রথমবার run-এ table-টা যেহেতু নেই, এই block skip; full data load. পরের run-এ শুধু new transaction. unique_key দিয়ে duplicate handle.
where transaction_at >= max - interval '3 days'. বা full_refresh মাঝে মাঝে।
৫ · Tests — data quality assertion
dbt-এর সবচেয়ে loved feature — built-in test. YAML-এ একটা লাইন লিখলে — প্রতিটি run-এ assertion check.
version: 2
models:
- name: customer_summary
description: "Daraz customer LTV — refreshed daily"
columns:
- name: customer_id
description: "Unique customer identifier"
tests:
- unique
- not_null
- name: order_count
tests:
- not_null
- dbt_utils.accepted_range:
min_value: 1
- name: lifetime_value_bdt
tests:
- not_null
- name: fct_transactions
columns:
- name: transaction_id
tests:
- unique
- not_null
- name: user_id
tests:
- not_null
- relationships:
to: ref('dim_users')
field: user_id
unique, not_null, accepted_values, relationships. dbt test command এ সব test চলে; fail হলে exit code non-zero — CI/CD ভাঙে। dbt_utils package-এ আরও ১০০+ test.
৬ · Sources — raw layer-এর declaration
dbt-এ raw data (ELT-এর "EL" থেকে আসা) "source" হিসেবে declare করতে হয়। YAML-এ:
version: 2
sources:
- name: raw
description: "Raw data ingested from operational systems"
schema: raw_daraz
tables:
- name: orders
description: "Order events from MySQL — ingested by Fivetran"
loaded_at_field: _fivetran_synced
freshness:
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}
columns:
- name: order_id
tests:
- unique
- not_null
- name: customers
loaded_at_field: updated_at
dbt source freshness — raw table-এ recent load-এর check. ১২ ঘণ্টা না update হলে warning, ২৪ ঘণ্টায় error. Pipeline upstream broken indicator.
৭ · Snapshot — slowly changing dimension
Daraz-এ আজ একটি customer-এর address "Dhaka", আগামীকাল "Chattogram". Old order Dhaka-এ মেপে দেখাবেন না Chattogram-এ? — এটি classic SCD (Slowly Changing Dimension) সমস্যা।
Snapshotdbt SnapshotSCD type-2 implementation. প্রতিটি change-এ valid_from / valid_to দিয়ে history track. dbt automatic detect ও handle করে। = SCD type-2-এর dbt implementation. প্রতি change-এ history-তে নতুন row যোগ; পুরাতন row-এ valid_to set.
{% snapshot customers_snapshot %}
{{ config(
target_schema='snapshots',
unique_key='customer_id',
strategy='timestamp',
updated_at='updated_at'
) }}
select * from {{ source('raw', 'customers') }}
{% endsnapshot %}
dbt snapshot চালালে — প্রতি new updated_at-এ history row যোগ। Reporting-এ historical join সম্ভব।
৮ · dbt Core বনাম dbt Cloud
-
dbt Core (free, open-source):
- CLI tool:
dbt run,dbt test,dbt docs serve. - আপনি hosting (Airflow, GitHub Actions) ব্যবস্থা।
- সব feature available.
- Bangladesh-এ ছোট team, cost-conscious — এটাই বেছে নেয়।
- CLI tool:
-
dbt Cloud (paid SaaS, $100+/dev/month):
- Browser-based IDE.
- Managed scheduler — Airflow আলাদাভাবে দরকার নেই।
- CI/CD built-in (PR check, slim CI).
- Hosted docs site, lineage UI.
- Bangladesh-এ বড় enterprise (BRAC bank, Robi)-এ আসছে।
৯ · একটি dbt project কেমন দেখায়
daraz_dwh/
├── dbt_project.yml # project-level config
├── profiles.yml # warehouse credentials (gitignored)
├── packages.yml # dbt-utils, dbt-expectations
├── models/
│ ├── staging/
│ │ ├── _sources.yml
│ │ ├── stg_orders.sql
│ │ ├── stg_customers.sql
│ │ └── stg_products.sql
│ ├── intermediate/
│ │ └── int_orders_with_customer.sql
│ └── marts/
│ ├── _marts.yml # tests, docs
│ ├── fct_orders.sql
│ ├── dim_customers.sql
│ └── customer_summary.sql
├── snapshots/
│ └── customers_snapshot.sql
├── tests/ # custom SQL tests
│ └── assert_revenue_positive.sql
├── seeds/ # static CSV → table
│ └── country_codes.csv
└── macros/ # reusable Jinja
└── generate_schema_name.sql
# Run commands:
dbt deps # install packages
dbt run # build all models
dbt test # run all tests
dbt docs generate # build docs
dbt docs serve # local docs site at :8080
dbt run dependency order-এ models build. Failed model-এর downstream skip. ১,০০০+ model-ও dbt smooth সামলায়।
~/.dbt/profiles.yml-এ রাখুন বা environment variable: password: "{{ env_var('DBT_PASSWORD') }}"।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ "ELT" নাকি "ETL" — dbt কোনটিকে enable করে এবং কেন? Bangladesh-এর context-এ এই shift practical কতটুকু?
dbt স্পষ্টভাবেই ELT-এর tool. বুঝতে হলে আগে তিনটি step-এর order বুঝে নিন।
ETL (পুরাতন paradigm, ১৯৯০-২০১০):
- Extract: source থেকে data বের করুন।
- Transform: আলাদা compute server (Informatica, Talend)-এ transform.
- Load: warehouse-এ load.
- Warehouse expensive ছিল — minimal data রাখা।
ELT (modern, ২০১৫+):
- Extract: source থেকে।
- Load: raw data সরাসরি warehouse-এ।
- Transform: warehouse-এর ভেতরেই SQL দিয়ে।
- Cloud warehouse (Snowflake, BigQuery) cheap ও fast — raw রাখা সম্ভব।
কেন ELT জিতছে:
- Cloud economics: Snowflake/BigQuery storage cents/GB. compute decoupled.
- Schema-on-read: raw রাখলে — পরে নতুন transformation possible original থেকে।
- SQL ubiquity: আরও বেশি লোক SQL জানে — Python/Spark কম।
- Vendor offload: Fivetran, Airbyte EL handle; dbt T.
dbt-এর ভূমিকা:
- "T" layer-এর tool.
- Raw warehouse-এ থাকা মানে — dbt-এর কাজের জায়গা warehouse.
- Spark/EMR-এর জটিল compute layer extra.
Bangladesh-এর reality:
- Cost concern: Snowflake credit-এ ১০ জন অ্যানালিস্টের warehouse — মাসে $২,০০০-৫,০০০। ছোট startup-এর জন্য বেশি।
- Alternative: ClickHouse self-hosted, BigQuery free tier ($৩০০ credit), Postgres warehouse pattern.
- EL tool: Fivetran expensive. Airbyte open-source — popular bd-তে। Custom Python script-ও common.
- Bandwidth: বড় data extract slow connection-এ — incremental EL critical.
- Skill gap: dbt শিখতে শুধু SQL + Git. এটি বড় advantage.
Practical scenarios:
- BRAC Bank reporting: ELT excellent — সব transaction Snowflake/Synapse-এ load, dbt-এ analytics.
- bKash fraud detection: ELT কাজে আসে না — sub-second latency দরকার, streaming ETL.
- Daraz BI dashboard: ELT perfect — overnight refresh যথেষ্ট।
- BTRC compliance reports: ELT — historical data যেমন ছিল accurately preserve.
Hybrid pattern:
- "ETLT" — light transform (PII masking, format) load-এর সময়; deep transform warehouse-এ।
- Operational systems-এ heavy compute না করতে।
মূল কথা: Cloud warehouse + dbt = analytics future. Bangladesh-এর enterprise এই path-এ আসছে। কিন্তু streaming ও ML inference আলাদা stack — ELT সবকিছুর সমাধান নয়।
প্র ০২ "Materialization" choice কঠিন। ১০০ GB transactions table-এ কখন view, কখন table, কখন incremental? ভুল choice-এর consequence কী?
Materialization decision = cost vs latency vs complexity trade-off. প্রতিটি model-এ আলাদা।
View — কখন:
- Source table ছোট (১ GB-র নিচে)।
- Query infrequent (প্রতিদিন ১-১০ বার)।
- Underlying data fresh চাই।
- Storage cost-sensitive.
View — সমস্যা ১০০ GB-তে:
- প্রতি query-তে ১০০ GB scan — Snowflake-এ ~$৫।
- BI tool ২০ user × ৫ refresh × $৫ = $৫০০/দিন!
- Slow — query-time-এ aggregation চলে।
Table — কখন:
- Read-heavy (BI dashboard, API).
- Source ছোট-মাঝারি (১০ GB-র নিচে rebuild affordable).
- Result-এ heavy aggregation/join — pre-compute.
Table — সমস্যা ১০০ GB-তে:
- প্রতি dbt run-এ ১০০ GB rebuild — ৩০ মিনিট, $৫০।
- প্রতিদিন rebuild = $১,৫০০/মাস শুধু এই model-এ।
- Run window দীর্ঘ — downstream wait.
Incremental — ১০০ GB-তে আদর্শ:
- প্রতি run-এ শুধু গতকালের ~৫০ MB process.
- Run time ৩০ সেকেন্ড, cost cents.
- Read fast (table-এর মতো)।
- Trade-off: complexity বেশি, late-arriving data risk.
Decision tree (১০০ GB transaction table):
- "Query কতবার?" — দিনে ১০+: not view.
- "Source কত বড়?" — ১০ GB-র বেশি: not pure table.
- "New row append-only?" — হ্যাঁ: incremental.
- "Update history?" — হ্যাঁ: snapshot বা full refresh weekly.
Recommended pattern (bKash transactions):
# staging: view (cheap, transparent)
stg_transactions: {{ config(materialized='view') }}
# fact: incremental (huge, append-mostly)
fct_transactions: {{ config(
materialized='incremental',
unique_key='transaction_id',
partition_by={'field': 'date', 'data_type': 'date'},
cluster_by=['user_id']
) }}
# summary: table (small, queried often)
daily_revenue_summary: {{ config(materialized='table') }}
ভুল choice consequences:
- View on huge: warehouse bill explosion. Query timeout. Dashboard load slow.
- Table on huge: long run time, schedule miss. Late refresh = stale dashboards.
- Incremental wrong key: duplicate rows, missing data.
- Table on small read-once: wasted storage, complexity.
Late-arriving data trap:
- Incremental-এ
WHERE date >= max(date)= older arriving row miss. - Solution: lookback window (
max - 3 days) + delete-insert. - Or weekly full_refresh:
dbt run --full-refresh -s fct_transactions.
মূল কথা: Materialization = engineering decision, business decision নয়। Volume measure, query pattern monitor, ব্যয় track — তারপর choose.
প্র ০৩ আপনার dbt project-এ ৫০০ model. Junior engineer একটা model পরিবর্তন করতে চায়। কোনগুলো affected হবে? কী CI/CD safeguard লাগে?
এটি real production scenario. dbt-এর lineage capability এখানে ভাল কাজে।
Affected detection:
# downstream impact
dbt list --select +my_model+
# (+ before = upstream, + after = downstream)
# শুধু changed model + downstream
dbt build --select state:modified+ \
--state ./prod-manifest
# Slim CI (PR-এ শুধু changed পরীক্ষা)
dbt build --select state:modified+ \
--defer --state ./prod-manifest
State comparison:
state:modified— current vs main branch-এ যা ভিন্ন।state:new— main-এ নেই।- "manifest.json" আগের build-এর — compare-এর basis.
CI/CD pipeline (GitHub Actions / GitLab):
name: dbt CI
on: pull_request
jobs:
ci:
steps:
- uses: actions/checkout@v3
- run: dbt deps
- run: dbt seed --target ci
- run: dbt build --select state:modified+ \
--defer --state ./prod-manifest \
--target ci
- run: dbt source freshness
Safeguard layers:
- Layer 1 — Static: SQL linter (sqlfluff), naming convention check.
- Layer 2 — Compile:
dbt parse— Jinja syntax error catch. - Layer 3 — Build: changed model + downstream actually build in CI schema.
- Layer 4 — Test: not_null, unique, custom assertion.
- Layer 5 — Compare: dbt-audit-helper দিয়ে old vs new diff.
- Layer 6 — Approval: senior reviewer approve.
- Layer 7 — Deploy: merge → production run.
Defer pattern:
- CI-তে শুধু changed model build.
- Upstream reference — production manifest থেকে।
- ৫০০ model-এর pretty কম resource.
- 10x+ faster CI.
Documentation enforcement:
- dbt-checkpoint hook: undocumented column reject.
required_docs: true— model description ছাড়া fail.
Test coverage:
- Primary key column-এ unique + not_null mandatory.
- Foreign key column-এ relationships test.
- Business rule (revenue > 0, status in valid list) custom test.
Production deployment:
- Blue-green: parallel schema build, atomic rename.
- Or zero-copy clone (Snowflake):
CREATE TABLE x_new CLONE x. - Rollback plan: previous run-এর schema retain (১ দিন)।
Junior onboarding patterns:
- Sandbox schema প্রতি dev-এর:
dbt_alice,dbt_bob. - Pull-request template — checklist (test added? doc updated? lineage checked?)।
- Pair programming — first ৩-৫ PR senior-এর সাথে।
Bangladesh enterprise context:
- Audit log requirement (BB compliance) — সব schema change tracked.
- Data lineage —
dbt docsgenerated diagram regulator-কে দেখানো। - PII handling — dbt-snowflake-এ row access policy + dbt macro.
মূল কথা: dbt + Git + CI/CD = software engineering rigor for analytics. ৫০০ model managing-এর জন্য এই disciplines essential — না হলে production pipeline বছরের পর বছর fragile.
প্র ০৪ "Macros" dbt-এ Jinja-ভিত্তিক reusable code. কোন situation-এ macro লেখা proper? Bangladesh fintech-এর জন্য একটা useful macro design করুন।
Macro = Jinja template যা compile-time-এ SQL generate করে। C-এর preprocessor-এর মতো।
কখন macro proper:
- DRY principle: একই SQL snippet ৩+ model-এ repeat.
- Database-specific abstraction: Snowflake vs BigQuery syntax difference hide.
- Dynamic generation: runtime input (variable) থেকে SQL.
- Custom test: built-in test যথেষ্ট না।
- Project conventions: schema naming, table aliasing standard.
কখন macro নয়:
- একবার ব্যবহৃত SQL — over-engineering.
- Business logic — model-এ থাকা ভাল (visible).
- Data-dependent logic — macro static, runtime data নয়।
Bangladesh fintech macro 1: BDT formatting
{% macro format_bdt(amount_col) %}
case
when {{ amount_col }} >= 10000000 then
concat(round({{ amount_col }} / 10000000.0, 2), ' কোটি')
when {{ amount_col }} >= 100000 then
concat(round({{ amount_col }} / 100000.0, 2), ' লাখ')
when {{ amount_col }} >= 1000 then
concat(round({{ amount_col }} / 1000.0, 2), ' হাজার')
else cast({{ amount_col }} as varchar)
end
{% endmacro %}
-- Usage:
select {{ format_bdt('total_revenue') }} as revenue_display
from fct_revenue
Bangladesh fintech macro 2: NID validation
{% macro is_valid_nid(nid_col) %}
-- Bangladesh NID: 10, 13, or 17 digits
({{ nid_col }} ~ '^[0-9]{10}$' or
{{ nid_col }} ~ '^[0-9]{13}$' or
{{ nid_col }} ~ '^[0-9]{17}$')
{% endmacro %}
-- Used in test:
{% test valid_nid(model, column_name) %}
select * from {{ model }}
where not {{ is_valid_nid(column_name) }}
and {{ column_name }} is not null
{% endtest %}
Bangladesh fintech macro 3: PII masking
{% macro mask_phone(phone_col) %}
case
when current_role() in ('analyst', 'admin') then {{ phone_col }}
else concat(left({{ phone_col }}, 5), 'XXXXXX')
end
{% endmacro %}
-- Bangladesh phone: 01XXXXXXXXX (11 digits)
-- Show: 01700XXXXXX
Bangladesh fintech macro 4: Fiscal year
{% macro fiscal_year(date_col) %}
case
when extract(month from {{ date_col }}) >= 7
then concat(extract(year from {{ date_col }}), '-',
extract(year from {{ date_col }}) + 1)
else concat(extract(year from {{ date_col }}) - 1, '-',
extract(year from {{ date_col }}))
end
{% endmacro %}
-- Bangladesh fiscal year: July-June
-- 2026-05 → "2025-2026"
-- 2026-08 → "2026-2027"
Bangladesh fintech macro 5: Mobile operator detection
{% macro mobile_operator(phone_col) %}
case
when {{ phone_col }} like '0170%' or {{ phone_col }} like '0171%' or
{{ phone_col }} like '0172%' or {{ phone_col }} like '0173%' or
{{ phone_col }} like '0174%' or {{ phone_col }} like '0175%' or
{{ phone_col }} like '0176%' or {{ phone_col }} like '0177%' or
{{ phone_col }} like '0178%' or {{ phone_col }} like '0179%' then 'Grameenphone'
when {{ phone_col }} like '0181%' or {{ phone_col }} like '0182%' or
{{ phone_col }} like '0183%' or {{ phone_col }} like '0184%' or
{{ phone_col }} like '0185%' or {{ phone_col }} like '0186%' or
{{ phone_col }} like '0187%' or {{ phone_col }} like '0188%' or
{{ phone_col }} like '0189%' then 'Robi'
when {{ phone_col }} like '019%' then 'Banglalink'
when {{ phone_col }} like '015%' then 'Teletalk'
when {{ phone_col }} like '013%' then 'Grameenphone' -- newer
else 'Unknown'
end
{% endmacro %}
Best practices:
- Macro file
macros/ফোল্ডারে। - Naming: verb-based (format_bdt, is_valid_nid).
- Document with docstring.
- Test macro itself (yes, possible).
- Package candidate: reusable macros → dbt package publish.
Public packages worth knowing:
- dbt-utils: generate_series, surrogate_key, pivot — daily use.
- dbt-expectations: Great Expectations port — advanced data tests.
- dbt-codegen: auto-generate model SQL from source schema.
মূল কথা: Macro = power tool — sparingly use. Business logic visible-এ থাকুক, plumbing macro-এ। Bangladesh-এর domain-specific macro অসাধারণ contribution হতে পারে।
অনুশীলন
-
লিখুন: bKash-এর daily transaction summary model — date, total_count, total_amount, unique_user_count.
stg_transactionsref করে।-- models/marts/daily_transaction_summary.sql {{ config(materialized='incremental', unique_key='transaction_date') }} select date(transaction_at) as transaction_date, count(*) as total_count, sum(amount) as total_amount_bdt, count(distinct user_id) as unique_user_count, avg(amount) as avg_amount_bdt from {{ ref('stg_transactions') }} where status = 'success' {% if is_incremental() %} and transaction_at >= (select coalesce(max(transaction_date), '1900-01-01') from {{ this }}) {% endif %} group by 1YAML test:
columns: - name: transaction_date tests: [unique, not_null] - name: total_amount_bdt tests: - dbt_utils.accepted_range: min_value: 0 -
Choose materialization: তিন model-এর জন্য কোনটি?
- (ক)
stg_users— ১০ মিলিয়ন row, ৫ GB, daily refresh. - (খ)
fct_clickstream— ৫০০ মিলিয়ন event/day, append-only. - (গ)
top_10_products— daily small aggregation, dashboard.
- (ক) view বা table — ৫ GB rebuild affordable. Read frequency দেখে decide.
- (খ) incremental — append-only fact, huge volume.
partition_by date. - (গ) table — ছোট, dashboard-এ frequent read, fast pre-compute.
- (ক)
-
Test design: Daraz-এর
fct_orders-এ কী কী test যোগ করবেন?columns: - name: order_id tests: [unique, not_null] - name: customer_id tests: - not_null - relationships: to: ref('dim_customers') field: customer_id - name: order_status tests: - accepted_values: values: ['pending', 'confirmed', 'shipped', 'delivered', 'cancelled'] - name: amount_bdt tests: - not_null - dbt_utils.accepted_range: min_value: 0 max_value: 10000000 # 1 কোটি cap - name: order_date tests: - not_null - dbt_utils.expression_is_true: expression: "<= current_date"Custom SQL test (tests/ folder):
-- tests/assert_no_future_orders.sql select * from {{ ref('fct_orders') }} where order_date > current_date
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ১৬ · Streaming vs Batch পরবর্তী পাঠ dbt batch-এর tool — streaming-এর জন্য ভিন্ন paradigm.
- পাঠ ১৪ · DAG লেখা ও schedule আগের পাঠ Airflow + dbt একসাথে চালালে dbt run-কে DAG task হিসেবে।
- পাঠ ২৫ · Data quality testing এই পাঠের সাথে সম্পর্কিত dbt test + Great Expectations — production data quality stack.
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।
pip install dbt-postgres বা dbt-bigquery দিয়ে শুরু করুন। অথবা
Google Colab-এ
DuckDB + dbt-duckdb adapter দিয়ে full project local-এ চালানো যায়।