分開 Python 底下幾種工作的,是資料以什麼單位進入程式。一次進來一筆、還是一次進來一整批,決定了要解的問題是什麼,也決定了工具鏈長什麼樣子。同一個語言標籤底下因此裝著幾組彼此不太相干的技術。

Web 後端:以一次請求用到的幾筆資料為單位

資料的單位是這次請求要用到的那幾筆。使用者按下一個按鈕,程式取出對應的幾列、改幾個欄位、寫回去,然後這次請求就結束了。

工具解的是把那幾筆安全地取出與改回去:ORM 把資料列包成物件、連線池管理與資料庫之間的連線、遷移工具讓表結構跟著程式一起演進。Django 與 FastAPI 這類框架的周邊生態幾乎都繞著這件事。

Web 後端的失敗形態跟著單位走。一次請求裡不小心打了一百次資料庫(每筆各查一次),或是把交易的範圍包得太大而讓鎖持有太久(一段時間內不讓別人動同一批列,範圍越大擋得越久),都是「一次應該只取幾筆」這個前提被破壞的結果。

資料工程與分析:以整張表或整批事件為單位

資料的單位是整張表,或某段期間的全部事件。沒有「這次請求」這種邊界,取而代之的是「這批」。

資料工程與分析的工具鏈因此分成三組,各解一件事:整批資料怎麼算(pandas 在單機記憶體裡算,Spark 把同一件事拆到多台機器上),轉換邏輯怎麼版本控管(dbt 把每一步轉換寫成可以被審閱與測試的模型),以及什麼時候算、失敗了怎麼重跑(Airflow 這類排程器)。

失敗形態也整組換掉:這批裝不裝得進記憶體、同一批會不會因為重跑而被算兩次、上游的欄位改了名字而下游整條流程靜默算出錯的結果。

機器學習:接在批次處理後面的數值矩陣

模型收的是一個數值矩陣。原始資料很少長成那個樣子,所以把它整理成矩陣的那一段仍然是批次處理——合併幾張表、把類別欄位轉成數值、補掉缺值、切出訓練與驗證。

pandas 在這裡是前置作業,PyTorch 這類框架接在它後面。機器學習與資料工程共用工具鏈的前半段,分歧在後半段。

自動化與系統工具:以一個檔案或一次執行為單位

自動化腳本處理的是檔案、程序與外部命令。單位是一個檔案或一次執行,資料本身是被搬運的內容。工具是 pathlib、subprocess、argparse 這一組,也就是 模組三 的內容。

系統與工具開發再往外一層:產出是被別人 import 或執行的程式,資料由使用者帶來。關心的是介面設計、相容性與封裝。

各組工作的失敗形態、判斷材料與檢索關鍵字的差異

單位決定了什麼事情會出錯,而這幾組的單位不同,出錯的形態就沒有交集。

把一次請求的查詢次數壓下來,靠的是理解物件與資料列之間的對應關係;判斷一批資料裝不裝得進記憶體,靠的是估算列數乘欄數乘每格佔幾個位元組。這兩種判斷用的材料完全不同,前一種做得再熟也不會讓後一種變容易。

檢索的結果跟著同一條軸分開。以物件關聯對映與請求生命週期為關鍵字找到的內容,與以 DataFrame 和排程為關鍵字找到的內容幾乎不重疊,因為它們描述的是不同的問題。一個人如果只用其中一組關鍵字搜尋,另一組的內容不會被結果帶到他面前——要看到它得先知道該用哪些詞。

這幾組工作在職務名稱上也各自分開,Python 只是它們共用的語言。

延伸閱讀:運算發生的位置、Web 後端的資料庫議題、商業分析指標、標準庫的檔案與外部命令工具

批次處理再往下切一刀:整批資料要嘛留在資料庫裡算,要嘛搬進程式的記憶體算。8.2 運算發生的位置 寫這條分界怎麼決定工具的形狀,以及 Python 存取資料庫的三種寫法為什麼全部落在資料庫那一側。

Web 後端的資料庫議題:一次請求該打幾次資料庫、交易邊界包到哪裡、ORM 的延遲載入什麼時候變成問題。backend 模組一 從這些形態進去,並給出每請求的查詢次數預算當判讀基準。

批次算出來的結果拿去做什麼:monitoring 模組八 寫留存、分群與轉換率各自怎麼定義,以及事件當初的屬性設計決定了哪些指標事後算得出來。

自動化的工具:模組三 收的是處理檔案與外部命令的標準庫,單位是一個檔案或一次執行。