PipeCraft

Roadmap Progress

ข้อมูลเบื้องต้นเกี่ยวกับวิศวกรรมข้อมูล (Introduction to Data Engineering) Python สำหรับ Data Engineering พื้นฐาน Linux & CLI สำหรับวิศวกรข้อมูล Git สำหรับระบบงานข้อมูลและทีมพัฒนา พื้นฐานเครือข่าย เว็บเทคโนโลยี และระบบกระจายศูนย์ (Web Fundamentals, Networking & Distributed Systems) SQL ขั้นสูง (Window Functions & Optimization) ฐานข้อมูลไม่ใช่เชิงสัมพันธ์ (NoSQL Databases & Modern Stores) การออกแบบโครงสร้างข้อมูล (Star/Snowflake & SCD) โครงสร้างพื้นฐานเครือข่ายระบบคลาวด์ (Cloud-based Networking) สถาปัตยกรรม Data Lakehouse (Apache Iceberg & MinIO) Local-first Data Engineering ด้วย DuckDB โครงสร้างพื้นฐานในรูปแบบโค้ด (IaC ด้วย Terraform) การแปลงข้อมูลระดับโปรด้วย dbt-core ข้อตกลงร่วมด้านข้อมูล (Data Contracts) การบริการและการส่งต่อข้อมูลวิเคราะห์ (Data Serving & Reverse ETL) การประมวลผลข้อมูลขนาดใหญ่แบบกระจายด้วย Apache Spark ระบบจัดการเวิร์กโฟลว์ข้อมูล (Airflow, Dagster & Prefect) การประมวลผลข้อมูลแบบเรียลไทม์ด้วย Kafka & Redpanda การจัดการคอนเทนเนอร์และคลัสเตอร์ (Containers & Kubernetes) ระบบ CI/CD และการเฝ้าระวังคุณภาพข้อมูล (CI/CD, Monitoring & Testing) ระบบความปลอดภัยและการควบคุมข้อมูล (Security, Governance & Privacy) ระบบปฏิบัติการและประมวลผลโมเดล (Machine Learning & MLOps) รากฐานของ AWS VPC การจัดการเส้นทางขั้นสูงและ NAT Gateway การเชื่อมต่อหลาย VPC และ Hybrid Cloud VPC Endpoints (PrivateLink) ระบบรักษาความปลอดภัยขอบเขตเครือข่าย สถาปัตยกรรมเครือข่ายสำหรับ EKS IPv6 และการจัดการ IP Address สถาปัตยกรรมเครือข่ายระดับโลก แก่นแท้ของสถาปัตยกรรม Kubernetes สถาปัตยกรรมเครื่องและคอมโพเนนต์ เลเยอร์ที่เชื่อมต่อได้ (Pluggable Layers) การรันบนโปรดักชันระดับองค์กร Apache Flink Stateful Stream Processing Real-Time CDC & Event Sourcing at Scale Low-Latency Stream-Table Joins & Windowing Data Lineage & Metadata Graph Engineering Statistical Anomaly Detection & Data Drift Data Incident Management & Automated DLQ Remediation Cloud Data FinOps & Cost Optimization Mechanics Data Mesh & Multi-Tenant Platform Architecture Vector Databases & AI-Ready Data Infrastructure API Fundamentals, Architectures & Core Components API Versioning, Docs, Real-Time & Microservices Production Reliability, Security & Resiliency World-Class Master Architecture & Traffic Management
บทที่ 4: การนำเข้าและการแปลงรูปข้อมูล (Data Ingestion & Transformation)

การแปลงข้อมูลระดับโปรด้วย dbt-core

4.1 กระบวนการเขียนตารางข้อมูลวิเคราะห์ด้วย dbt-core

dbt ปรับเปลี่ยนการทำ Data Transformation ให้มีมาตรฐานเดียวกับวิศวกรรมซอฟต์แวร์ ทั้งเรื่อง Version Control, Modular Data Modeling, Data Testing, และ Documentation อัตโนมัติในระดับ Production

Technical Architecture Diagram

Architecture Diagram
Click to zoom
Step-by-Step Breakdown: (1) Data Source Ingestion -> (2) Processing Engine -> (3) Storage Layer -> (4) Serving API

1. วิศวกรรมข้อมูลวิเคราะห์และการคอมไพล์กราฟแสดงความสัมพันธ์ (DAG Compilation)

Learning Progression

  • [BASIC] ปูพื้นฐานภาษาเข้าใจง่าย - เข้าใจคอนเซปต์ภาพรวมและการแก้ปัญหาเบื้องต้น
  • [INTERMEDIATE] โค้ด/คอนฟิกไวยากรณ์จริง - การเขียนโค้ดเพื่อใช้งานจริงในระบบ
  • [PROFESSIONAL] Under-the-hood & Performance/FinOps - กลไกเบื้องลึกและการรีดประสิทธิภาพ

Real-World Enterprise Scenario

เคสระบบการเงิน/Big Tech: การรองรับ Transaction จำนวนมหาศาลต่อวินาทีพร้อมประกัน Data Integrity สูงสุด โดยใช้สถาปัตยกรรมที่ยืดหยุ่นและการมอนิเตอร์ระดับสูง

ทฤษฎีและกลไกการทำงาน (How it works): dbt-core ทำงานในฐานะคลังเก็บโค้ด SQL ที่จัดรูปเป็นแบบระบุปลายทาง (Declarative) โดยใช้คำสั่งระบุความสัมพันธ์เป้าหมายด้วยคำฟังก์ชัน `ref()` และ `source()`. เมื่อสั่งรันคำสั่ง ตัว dbt จะสแกนโฟลเดอร์ไฟล์โมเดลทั้งหมดเพื่อทำการสร้างและคอมไพล์ **Directed Acyclic Graph (DAG)** เพื่อแสดงความสัมพันธ์การไหลของตารางข้อมูล ก่อนจะสร้างคำสั่ง DDL (Data Definition Language) ยิงไปประมวลผลบนคลังข้อมูลปลายทางโดยตรงตามลำดับชั้นความสัมพันธ์ที่ถูกต้อง

-- Defining dependencies inside dbt models using Jinja functions
-- models/marts/fct_weekly_sales.sql
WITH daily_orders AS (
    SELECT * FROM {{ ref('stg_orders') }} -- Tells dbt compiler to compute stg_orders first
),
customer_details AS (
    SELECT * FROM {{ ref('dim_customers') }}
)
SELECT ...
                    

Use Case ในชีวิตจริง (Real-world Scenario): คลังข้อมูลของบริษัทประกันภัยที่มีโมดูล SQL เชื่อมต่อกันกว่า 500 ตาราง การเปลี่ยนโครงสร้างฟิลด์ในตารางฐานล่าง dbt ช่วยระบุความเกี่ยวข้องข้ามสายและไล่แปลงค่าตารางในชั้นถัดไปตามลำดับโดยไม่สร้างความขัดแย้งเชิงโครงสร้าง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การเกิดโครงสร้างความสัมพันธ์แบบลูปวงกลม (Circular Dependency เช่น ตาราง A เรียก B และ B เรียก A) ซึ่งจะทำให้คอมไพเลอร์ของ dbt รันไม่ผ่าน แก้ไขโดยถอดถอนตรรกะประมวลผลย่อยออกมาสร้างตารางสะพานตัวกลาง (Bridge model) เพื่อตัดการเชื่อมโยงวงกลม

2. ยุทธวิธีการบันทึกตารางทางกายภาพ (Materialization Strategies)

ทฤษฎีและกลไกการทำงาน (How it works): dbt สนับสนุนการทำ Materializations ซึ่งคือการเลือกแปลงรหัส SQL ไปจัดเก็บเป็นสเตทจริงบนฐานข้อมูล 4 รูปแบบ: 1. **View**: สร้างวิวคิวรีจำลองขึ้นมา ไม่เปลืองพื้นที่ดิสก์ แต่จะคำนวณใหม่ทุกครั้งที่มีการเรียกสืบค้นข้อมูล 2. **Table**: บิวด์สร้างตารางดิสก์จริงเต็มรูปแบบ โดยจะรันคำสั่งลบและบิวด์ตารางใหม่ทั้งหมดในทุกครั้งที่รัน (Drop and Recreate) ปลอดภัยต่อข้อมูลนิ่งแต่กินเวลาการประมวลผลสูง 3. **Ephemeral**: แปลงโมเดลเป็นโครงสร้างย่อย (Common Table Expression - CTE) ไปสอดแทรกในโมเดลถัดไปแทนการเขียนลงฐานข้อมูล 4. **Incremental**: ประมวลผลและแทรกเฉพาะข้อมูลพาร์ทิชันแถวใหม่ที่เพิ่มขึ้น ช่วยเซฟเวลาและงบประมาณการดึงข้อมูล OLAP คลาวด์ได้สูงสุด

# Configuration inside dbt model block defining materialization type
# models/staging/stg_orders.sql
{{ config(
    materialized='table',
    indexes=[{'columns': ['order_id'], 'type': 'btree'}]
) }}
                    

Use Case ในชีวิตจริง (Real-world Scenario): การนำข้อมูลดิบล็อกการกดเว็บระดับหลายกิกะไบต์มาทรานฟอร์ม วิศวกรข้อมูลเลือกใช้โมเดลประเภท `incremental` รันงานอัปเดตสรุปพฤติกรรมลูกค้าทุกชั่วโมง เพื่อเลี่ยงภาระค่าประมวลผลจากการที่ต้องรันสแกนข้อมูลเดิมซ้ำไปมา

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การรันโมเดลแบบ Table บนฐานข้อมูลขนาดใหญ่เป็นร้อยล้านแถวทำให้เกิดความล่าช้าและเปลืองค่าคอมพิวต์คลาวด์ แก้ไขโดยปรับเปลี่ยนสเปคโมเดลเหล่านั้นให้มาใช้กลไก `incremental` โดยกรองดักเฉพาะฟิลด์แก้ไขล่าสุด

3. กลไกยุทธวิธีประมวลผลส่วนต่าง (Incremental Models - Append-Only & Merge)

ทฤษฎีและกลไกการทำงาน (How it works): ในโหมดการรันแบบส่วนต่าง dbt จะประยุกต์ใช้งาน 2 รูปแบบย่อยเพื่อซิงก์ข้อมูลเข้าตารางเป้าหมาย: - **Append-only**: นำระเบียนข้อมูลใหม่ไปเขียนต่อท้ายตารางโดยตรงอย่างรวดเร็ว เหมาะสำหรับตารางล็อกเหตุการณ์ที่ไม่เคยมีการแก้ไขย้อนหลัง - **Merge**: นำคีย์หลัก (Unique Key) ของข้อมูลชุดใหม่มาเทียบชนกับตารางหลัก หากคีย์ตรงกันจะสั่งอัปเดตฟิลด์ (Update) หากไม่เจอจะสั่งแทรกแถวใหม่ (Insert) ช่วยรักษาความสะอาดไม่ให้เกิดรายการแถวซ้ำซ้อน - **Insert-Overwrite**: เขียนทับข้อมูลทั้งพาร์ทิชัน (เช่น รายวัน) ด้วยข้อมูลใหม่ทั้งหมด เหมาะกับข้อมูลที่มีการเปลี่ยนแปลงบ่อยในระดับพาร์ทิชัน - **Microbatching**: ทยอยรันข้อมูลทีละชุดเล็กๆ ตามช่วงเวลา (เช่น ทุก 1 ชั่วโมง) เพื่อลดภาระหน่วยความจำและทำให้ข้อมูลใกล้เคียงเรียลไทม์มากขึ้น

-- Incremental configuration using merge strategy
-- models/marts/fct_orders.sql
{{ config(
    materialized='incremental',
    unique_key='order_id',
    incremental_strategy='merge'
) }}

SELECT * FROM {{ ref('stg_orders') }}
{% if is_incremental() %}
  -- Filter records updated within the last lookback window
  WHERE order_updated_at >= (SELECT MAX(order_updated_at) FROM {{ this }})
{% endif %}
                    

Use Case ในชีวิตจริง (Real-world Scenario): ตารางประวัติยอดขายสินค้าของระบบอีคอมเมิร์ซที่สถานะคำสั่งซื้อสามารถเปลี่ยนจาก "กำลังจัดส่ง" ไปเป็น "จัดส่งสำเร็จ" การใช้ Merge Strategy ในโหมด Incremental ช่วยอัปเดตสถานะของออร์เดอร์เดิมได้อย่างถูกต้องครบถ้วน

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ความผิดพลาดของผลรวมยอดในตารางปลายทางหากมีข้อมูลเก่าที่ยกเลิกไปแล้วไม่ถูกตามไปล้างทิ้ง แก้ไขโดยเปิดใช้งานคำสั่งรันแบบล้างประวัติใหม่บางส่วน (Full refresh rebuild) สัปดาห์ละครั้ง

4. การจัดการข้อมูลตกหล่นหรือมาสายด้วย Lookback Windows ใน SQL

ทฤษฎีและกลไกการทำงาน (How it works): ปัญหาคลาสสิกของท่อส่งแบบส่วนต่างคือ **Late-arriving Data** ข้อมูลเกิดเมื่อวานแต่เพิ่งส่งมาถึงคลังวันนี้เนื่องจากระบบเน็ตเวิร์กของแอปพลิเคชันสะดุด หากเรากรองดึงเฉพาะข้อมูลที่เกิดขึ้นหลังเวลาสูงสุดปัจจุบันของตาราง ข้อมูลที่มาสายกลุ่มนี้จะหลุดรอดการประมวลผลถาวร วิธีแก้ไขคือการเขียนตรรกะเผื่อเวลาคิวรี่ย้อนหลังเรียกว่า **Lookback Window** โดยขยับเวลาเริ่มต้นการดึงข้อมูลย้อนหลังไปเผื่อ เช่น 3 วันล่าสุดเสมอ และพึ่งพา Merge strategy เพื่อลบอัปเดตแถวเก่าซ้ำซ้อน

-- Implementing a 3-day lookback window inside dbt incremental logic
SELECT * FROM {{ ref('stg_events') }}
{% if is_incremental() %}
  -- Scan last 3 days to capture delayed telemetry events
  WHERE event_timestamp >= (SELECT DATEADD(day, -3, MAX(event_timestamp)) FROM {{ this }})
{% endif %}
                    

Use Case ในชีวิตจริง (Real-world Scenario): แอปพลิเคชันมือถือออฟไลน์ของลูกค้าที่จดบันทึกยอดใช้งานเก็บในโทรศัพท์และเพิ่งมาซิงก์ส่งข้อมูลเมื่อลูกค้าหาสัญญาณเน็ตเจอ ระบบ Lookback Window ช่วยให้แต้มสะสมและสถิติยอดใช้ของแอปถูกคำนวณรวมย้อนหลังได้อย่างไม่ผิดพลาด

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การกำหนด Lookback Window กว้างเกินไป (เช่น สแกนย้อนหลัง 30 วันในทุกๆ ชั่วโมง) จะทำให้ท่อประมวลผลใช้เวลานานขึ้นและเสียค่าคอมพิวต์สูงเกินความจำเป็น แก้ไขโดยการประเมินสถิติเวลาล่าช้าเฉลี่ย (SLA tracking) เพื่อกำหนดระยะ Lookback ให้เหมาะสมที่สุด

5. โครงสร้างการทดสอบ 5 เลเยอร์และมิติวัดคุณภาพข้อมูล (Enterprise Data Quality Testing)

ทฤษฎีและกลไกการทำงาน (How it works): การเขียน dbt test เป็นเพียงหนึ่งในจิ๊กซอว์ของ สถาปัตยกรรมทดสอบข้อมูล 5 เลเยอร์ (5-Layer Testing Architecture) ซึ่งประกอบด้วย:
1. Unit Testing: จำลองทดสอบตรรกะแปลงข้อมูลในเมมโมรี่ (เช่น pytest/Mock DataFrame)
2. Schema Assertions: บังคับใช้ Data Contract ดักจับตั้งแต่จุด Ingestion (เช่น Pandera)
3. Integration Testing: จำลอง DB ด้วย Testcontainers เพื่อทดสอบการอ่านเขียนข้าม Network
4. Data Warehouse Integrity: ใช้ dbt test เช็คความสมบูรณ์หลังทำโมเดล
5. Data Quality Observability: เฝ้าระวัง Data Drift ก่อนเข้าแดชบอร์ด (เช่น Great Expectations)

ในเลเยอร์ที่ 4 (Warehouse Integrity) dbt จะทดสอบข้อมูลตาม มิติวัดคุณภาพ 6 มิติ (6 Pillars of DQ) โดยเฉพาะเรื่อง Uniqueness (ห้ามคีย์ซ้ำ), Completeness (ห้ามเว้นว่าง Not Null), Validity (Accepted Values), และ Consistency (ความสัมพันธ์ตรงกันข้ามระบบ Referential Integrity)

# Configuration scheme mapping the 6 Pillars of DQ in dbt YAML
# models/schema.yml
version: 2

models:
  - name: dim_customers
    columns:
      - name: customer_key
        tests:
          - unique     # DQ Pillar: Uniqueness
          - not_null   # DQ Pillar: Completeness
      - name: status
        tests:
          - accepted_values: # DQ Pillar: Validity
              values: ['active', 'inactive', 'pending']
                    

Use Case ในชีวิตจริง (Real-world Scenario): ทุกครั้งที่วิศวกรข้อมูลรวมโค้ดและส่งขึ้นระบบโปรดักชัน ระบบ CI/CD จะสั่งรันคำสั่ง dbt test เพื่อตรวจสอบความสมบูรณ์ของยอดสถิติตาราง หากพบว่ามีข้อมูลแถวใดที่คีย์หลักซ้ำซ้อน (ละเมิด Uniqueness) ระบบจะสั่งยกเลิก Deployment เพื่อไม่ให้ข้อมูลพังไหลขึ้นระบบจริง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การรันระบบทดสอบที่ซับซ้อนเกินไป (เช่น เช็ค Consistency ข้ามไปมาหลายตาราง) บนข้อมูลขนาดใหญ่ระดับร้อยล้านแถวอาจเปลืองค่าประมวลผลคิวรีสูงมาก แก้ไขโดยหลีกเลี่ยงการทดสอบแบบ Join ตารางหนาแน่นในชั้น dbt และย้ายการเช็คเชิงลึกไปทำที่เลเยอร์ Data Contract หรือใช้เครื่องมือ Observability ตรวจจับสถิติความเบี่ยงเบนแทน

6. dbt Semantic Layer (Metricflow)

ทฤษฎีและกลไกการทำงาน (How it works): dbt Semantic Layer (ขับเคลื่อนโดย Metricflow) ช่วยให้องค์กรสามารถนิยามตัวชี้วัด (Metrics) เช่น รายได้ (Revenue) หรือ จำนวนลูกค้า (Active Users) ไว้ที่ส่วนกลางแทนที่จะเขียน SQL ซ้ำๆ ในหลาย Dashboard

# models/metrics/revenue.yml
metrics:
  - name: revenue
    description: "Total revenue from completed orders"
    type: simple
    type_params:
      measure: total_amount
    meta:
      has_pii: false
                    

Use Case ในชีวิตจริง (Real-world Scenario): ทีมการตลาดและทีมการเงินดึงตัวเลข "ยอดขายประจำเดือน" ไปใช้ใน Tableau และ PowerBI โดยได้ตัวเลขตรงกันเสมอเพราะดึงจาก Semantic Layer เดียวกัน

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การออกแบบ Dimension และ Measure ที่ซับซ้อนเกินไปอาจทำให้คิวรี่ช้า แก้ไขโดยการทำ Pre-aggregation หรือการทำ Caching

7. dbt Mesh (Cross-project References)

ทฤษฎีและกลไกการทำงาน (How it works): เมื่อองค์กรขยายใหญ่ขึ้น การมี dbt project เดียว (Monolith) จะทำให้รันช้าและจัดการยาก dbt Mesh อนุญาตให้แบ่งโปรเจกต์ย่อยและอ้างอิงโมเดลข้ามโปรเจกต์ได้ผ่าน `{{ ref('project_name', 'model_name') }}`

-- models/marts/marketing_roi.sql
SELECT * FROM {{ ref('finance_project', 'fct_revenue') }} -- Cross-project reference
                    

Use Case ในชีวิตจริง (Real-world Scenario): ทีมการตลาดสามารถอ้างอิงตารางรายได้ (Revenue) ที่ทีมการเงินดูแลอยู่ได้โดยตรง โดยไม่ต้องก็อปปี้โค้ดหรือรอให้ทีมการเงินสร้างวิวให้

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การผูกมัด (Coupling) ระหว่างโปรเจกต์อาจทำให้เกิดปัญหาเมื่อโปรเจกต์ต้นทางเปลี่ยนสกีมา แก้ไขโดยใช้ Data Contracts ระหว่างโปรเจกต์ (Model Contracts)

8. Custom Materializations

ทฤษฎีและกลไกการทำงาน (How it works): หาก Materialization มาตรฐาน (Table, View, Incremental) ไม่ตอบโจทย์ dbt เปิดให้เขียน Jinja macro เพื่อกำหนดวิธีการสร้างตารางด้วยตัวเอง (Custom Materialization)

{% materialization custom_insert_only, default %}
  {%- set target_relation = api.Relation.create(identifier=model['alias'], schema=schema, database=database) -%}
  {% call statement('main') -%}
    INSERT INTO {{ target_relation }} ( {{ sql }} );
  {%- endcall %}
  {{ return({'relations': [target_relation]}) }}
{% endmaterialization %}
                    

Use Case ในชีวิตจริง (Real-world Scenario): ต้องการยิงข้อมูลเข้าสู่ระบบปลายทางที่เป็นฐานข้อมูลแบบพิเศษที่ต้องการคำสั่ง SQL เฉพาะเจาะจง (เช่น ClickHouse หรือระบบ Real-time เฉพาะ)

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การเขียน Custom Materialization เองอาจเกิดข้อผิดพลาดในการจัดการ State ของข้อมูล (เช่น ข้อมูลซ้ำ) จึงต้องเขียนโค้ดรองรับกรณีล้มเหลว (Idempotency) ให้ดี

Weekend Sandbox Challenge: Configure Incremental Model in dbt

โจทย์ปฏิบัติการ: จงเขียนระเบียบโมเดล SQL ใน dbt เพื่อบันทึกข้อมูลแบบเพิ่มส่วนต่าง (Incremental Model) โดยระบุคีย์หลักในการทำ Merge และกรองขอบเขตวันเวลารันย้อนหลังเพื่อดึงข้อมูลอย่างคุ้มค่า

-- weekly_sales.sql
{{ config(
    materialized='incremental',
    unique_key='week_id',
    incremental_strategy='merge'
) }}

SELECT 
    DATE_TRUNC('week', order_date) as week_id,
    SUM(amount) as total_revenue
FROM {{ ref('stg_orders') }}
{% if is_incremental() %}
    WHERE order_date >= (SELECT DATEADD(day, -3, MAX(week_id)) FROM {{ this }}) -- 3-day lookback window
{% endif %}
GROUP BY 1
                    

Senior Technical Interview Q&A

Q1: อะไรคือความแตกต่างเชิงกำลังและค่าคิวรี่ระหว่างกลไก Table Materialization และ Incremental Materialization ใน dbt?

A1: Table materialization จะสร้างตารางขึ้นใหม่หมดทุกรอบการรัน (Drop & Recreate) ซึ่งประมวลผลข้อมูลปริมาณยักษ์ซ้ำซาก สิ้นเปลืองทั้งเวลาและค่าใช้จ่ายคลาวด์มหาศาล ในขณะที่ Incremental materialization ดึงเฉพาะแถวข้อมูลใหม่หรือแถวที่เปลี่ยนสเปคมาทับตารางเป้าหมายเดิมผ่านคำสั่ง `MERGE` ช่วยสปีดและประหยัดงบระบบได้สูงสุด

Q2: เราควรดีไซน์แก้ไขปัญหาท่อส่งดึงข้อมูลล่าช้า (Late-arriving data) ในโครงสร้าง Incremental ของ dbt อย่างไร?

A2: กำหนดกรอบการดึงข้อมูลย้อนหลังเผื่อเวลา (Lookback Window) ในคำสั่งกรอง โดยคำนวณย้อนหลัง เช่น `MAX(date) - INTERVAL '3 DAYS'` แทนที่จะดึงเฉพาะจุดล่าสุด และใช้คุณสมบัติ `unique_key` ร่วมกับ `merge` strategy เพื่อให้ dbt ทำลายแถวประวัติเดิมทิ้งก่อนแทรกค่าแก้ไขใหม่

ข้อดี / จุดเด่น & ข้อเสีย / ข้อควรระวัง

ข้อดี / จุดเด่น

  • ทำให้การพัฒนา SQL เป็นระเบียบและลดการเขียนโค้ดซ้ำซ้อนได้ดีเยี่่ยม
  • มีระบบเขียนเช็คคุณภาพข้อมูลและบันทึกเอกสารความสัมพันธ์อัตโนมัติในตัว

ข้อเสีย / ข้อควรระวัง

  • ทำได้แค่ด้านแปลงข้อมูล (T) เท่านั้น ไม่ได้รองรับการดึงข้อมูลจากต้นทางข้ามแหล่ง
  • ต้องอาศัยการวางแผนการประมวลผลรันเครื่องเซิร์ฟเวอร์คลังข้อมูลจริงในการคำนวณ

ปฏิบัติการจริง (Lab Practice)

Bilingual Guide

แล็บ: พัฒนาและรันชุดโมเดลวิเคราะห์ข้อมูลผ่าน dbt

วิธีรันแล็บปฏิบัติการบนเครื่องจริง (Local Terminal Execution Blueprint)

เนื่องจากปฏิบัติการ Data Engineering / DevOps ระดับสูงต้องรันบน Environment จริง ขั้นตอนด้านล่างนี้คือคำสั่งสำหรับนำไปรันบน Terminal / Docker ในเครื่องของคุณ:

1. สร้างโฟลเดอร์ปฏิบัติการและเตรียมไฟล์ Environment
mkdir -p pipecraft-lab && cd pipecraft-lab
python3 -m venv venv && source venv/bin/activate
pip install --upgrade pip pandas polars pytest requests
2. จำลองการสร้างและรันระบบประมวลผล (Run Pipeline Command)
# Run execution pipeline test
python3 -c "
import polars as pl
print(' [PipeCraft Lab] Running local pipeline engine...')
df = pl.DataFrame({'id': [1, 2, 3], 'status': ['SUCCESS', 'SUCCESS', 'AUDITED']})
print(df)
" 
3. ตรวจสอบการผ่านเกณฑ์และการทำงาน (Data Quality Assertions)
# Verify clean execution exit status
echo " PipeCraft Local Lab Execution Completed Successfully!"

💡 คำแนะนำ & ทริกเด็ด

สำหรับโปรเจกต์ขนาดใหญ่ แนะนำให้เขียนโมเดลทดสอบไว้ในสภาพแวดล้อมจำลอง (Dev schema) เพื่อไม่ให้คิวรีเขียนไปทับตารางจริงบนโปรดักชันจนกว่ารหัสจะผสานสายหลัก