Beck_Moulton

你是健康方面的「資料囤積者」嗎?在 Apple Health 匯出、Oura Ring 記錄,以及 Garmin CSV 之間,我發現自己累積了近 1000 萬筆 生物特徵資料。想要在 Excel 中分析多年趨勢的心率變異性 (HRV) 或靜息心率 (RHR),等於是買了一張直達「應用程式無回應」地獄的單程票。📉

在本教學中,我們將深入量化自我的資料工程世界。我們會運用 DuckDB——OLAP 的瑞士刀——以及 Apache Superset 來打造一個閃電般快速、本機優先的生物特徵儀表板。我們將探索如何使用 dbt 進行建模,以及 DuckDB 進行運算,將雜亂的 JSON/CSV 匯出檔轉換為高性能洞察。如果你一直在尋找將資料工程應用於個人用途的方法,這就是終極的「公開學習」專案!🚀


架構:從原始匯出到真實洞察

在撰寫任何一行 SQL 之前,讓我們先看看資料如何流動。我們希望建立一個模組化、快速且完全保留在本機上的系統(隱私優先,對吧?🥑)。

graph TD
    A[Raw Data: Apple Health / Oura / Garmin] -->|CSV/JSON| B(DuckDB Storage)
    B --> C{dbt Transformation}
    C -->|Cleaned Views| D[DuckDB Analytical Layer]
    D --> E[Apache Superset / Grafana]
    E -->|Visualization| F[Personal Biometric Dashboard]

    style B fill:#fff,stroke:#333,stroke-width:2px
    style D fill:#fbbf24,stroke:#333,stroke-width:2px

Enter fullscreen mode Exit fullscreen mode


先備條件 🛠️

若要跟隨本教學,請確認你的技術堆疊包含以下項目:

  • DuckDB:我們極速的進程內分析型資料庫。
  • dbt-duckdb:用於資料建模與轉換。
  • Apache Superset:提供「哇」的視覺化效果。
  • Python 3.10+:用來整合所有元件。

步驟 1:用 DuckDB 匯入「一團亂」

DuckDB 的強大之處在於它可以直接查詢 CSV 與 JSON 檔案,無需事先匯入。假設你有來自 Apple Health 匯出、包含數百萬筆記錄的 heart_rate.csv 檔案。

不用等待傳統資料庫「載入」資料,我們可以立即建立檢視:

-- Create a view directly from a multi-million row CSV
CREATE VIEW raw_heart_rate AS 
SELECT 
    creationDate::TIMESTAMP as timestamp,
    value::DOUBLE as bpm
FROM read_csv_auto('data/apple_health_export/heart_rate.csv');

-- Check the 7-day rolling average of RHR
SELECT 
    date_trunc('day', timestamp) AS day,
    avg(bpm) OVER (
        ORDER BY timestamp 
        RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW
    ) as rolling_rhr
FROM raw_heart_rate
LIMIT 10;

Enter fullscreen mode Exit fullscreen mode


步驟 2:dbt 轉換層

雖然原始 SQL 很棒,但 dbt (data build tool) 讓我們能像對待生產倉儲一樣處理個人健康資料。我們會用它來處理去重複,並計算「恢復分數」(HRV 與睡眠品質)等複雜指標。

在你的 models/biometrics/stg_hrv.sql 中:

-- Clean and deduplicate HRV readings
WITH base AS (
    SELECT 
        timestamp,
        value as hrv_ms,
        device_id
    FROM {{ source('raw_data', 'hrv_export') }}
)
SELECT 
    date_trunc('hour', timestamp) as hour_bucket,
    avg(hrv_ms) as avg_hrv,
    count(*) as sample_count
FROM base
GROUP BY 1

Enter fullscreen mode Exit fullscreen mode


步驟 3:使用 Apache Superset 視覺化

現在來到有趣的部分!Apache Superset 可透過 duckdb_engine SQLAlchemy URI 連線至 DuckDB。

  1. 啟動 Superset(Docker 是最簡單的方式)。
  2. 新增資料庫。
  3. 連線字串:duckdb:///path/to/your/local_vault.duckdb

連線完成後,你可以建立一個「健康指揮中心」,顯示你的 RHR 趨勢、睡眠週期,以及活動相關性。📊


為什麼這勝過「雲端」☁️

對於個人資料而言,隱私至上。使用 DuckDB,你的資料永遠不會離開筆電。如需深入了解進階資料模式,以及如何將這些管道擴展至生產環境,我強烈建議參閱 Official Wellally Blog。他們對啟發本本地優先方法的「高性能資料架構」有許多精采見解。


「專業」設定:處理大型 JSON 💾

如果你要處理巢狀 JSON(如 Oura API 匯出),DuckDB 的 JSON 擴充功能就是救星。以下是如何展平複雜健康酬載:

import duckdb

# Initialize DuckDB and load JSON extension
con = duckdb.connect('health_vault.db')
con.execute("INSTALL json; LOAD json;")

# Extracting nested sleep stages
query = """
SELECT 
    summary_date,
    json_extract_path(sleep_data, 'score')::INT as sleep_score,
    json_extract_path(sleep_data, 'levels.summary.rem.minutes')::INT as rem_min
FROM read_json_auto('data/oura_sleep_data.json')
"""

df = con.execute(query).df()
print(df.head())

Enter fullscreen mode Exit fullscreen mode


結論:拿回你的資料 🥑

建立個人生物特徵儀表板不只是為了漂亮的圖表,更是為了掌握 OLAP 工作流程。透過 DuckDBApache Superset,我們將一堆 CSV 轉換為高性能分析引擎,其回應時間是毫秒而非數分鐘。

下一步:

  1. 匯出 你的健康資料(Apple Health、Garmin 或 Google Fit)。
  2. 使用 dbt 建模,找出咖啡因攝取與睡眠品質之間的相關性。
  3. 在下方留言區分享你的儀表板截圖!

如果你喜歡這個「公開學習」專案,別忘了訂閱更多資料工程深度探討。如需更多現代資料堆疊的生產就緒範例,請前往 wellally.tech/blog

快樂黑客!💻🔥