多一欄也可能把數量讀錯
報表新增品質欄,看起來只是多一個資訊,但舊匯入程式可能按第三欄取數量。新欄插在中間後,程式把品質代碼一當成數量一,甚至不會報錯。相容性要驗證每個欄位最後被如何解讀,不能只看檔案能開啟或匯入回傳成功。
先列出所有使用者與程式:人工試算表、排程匯入、資料庫載入、客戶介面與歷史重播。每個接收者保存軟體版本、欄位映射方式、型別與錯誤策略。只測最新版自己的程式,不能代表仍在使用舊版的下游也相容。
建立舊契約基準,包含欄名、順序、必填、型別、單位、空值、編碼、引號與日期格式。新增欄位時同時標出是否改變其他欄位語意;把溫度欄由原始整數改成攝氏小數,不能只說「加了品質欄」而忽略真正破壞相容性的變更。
本文適用於CSV報表與資料庫匯入流程,以Python csv及PostgreSQL COPY文件說明解析界面。不保證特定HMI或PLC檔案讀取指令會忽略多餘欄位,也不提供未核對的欄位上限;受限設備須查指定版本文件並實測。
用一筆資料暴露位置映射問題
舊版三欄為事件編號、溫度、數量,資料E01、25.3、5。新版在數量前加入品質代碼,四欄變成E01、25.3、1、5。若舊程式仍讀第三欄,數量會錯成1;應在測試資料中故意讓品質與數量不同,才不會被相同數字掩蓋。
位置映射必須按版本選正確欄序,或改成經驗證的欄名映射。欄名映射也不是自動免疫:名稱拼錯、重複欄名、前後空白與BOM,都可能讓欄位找不到或覆蓋。先檢查標題唯一且完全符合契約,再解析資料。
把新欄加在最後,可能減少部分位置程式的影響,但不能當成普遍保證。有些接收者要求固定欄數,遇到第四欄就拒絕;有些會忽略,有些會全部塞入錯誤位置。每種行為都必須用實際下游版本驗證。
新增欄位若是選填,定義舊檔沒有它時如何表示。品質未知不能自動補為良好,倍率缺少也不能一律當一;預設值必須在業務上成立。接收者無法安全解讀時,明確拒絕並保留檔案,比靜默填入誤導值更可診斷。
完成後,舊版檔與新版檔各有明確接受或拒絕結果;被接受的E01溫度仍為25.3、數量仍為5,品質依版本正確標示。拒絕也可以是符合契約的結果,前提是錯誤清楚且不留下部分錯誤資料。
把解析成功與業務正確分兩層驗收
Python DictReader按欄名組成字典,但多餘或不足的資料欄仍有自己的處理規則,不能因得到字典就認定欄數正確。先驗證標題與每列欄數,再驗證必要欄位及型別;缺欄與欄位內容為空也要分開。
資料庫匯入也要使用明確欄位清單與版本對照。PostgreSQL COPY有指定目標欄位的方式,檔案欄位必須按對應清單理解;不要把有標題列誤認成所有匯入工具都會自動按名稱重排。實際標題檢查選項依版本與設定核對。
第一層測語法:編碼、分隔符號、引號與欄位個數。第二層測語意:25.3是否仍是攝氏、數量是否仍是整數件數、事件時間是否仍帶相同時區。第三層查副作用:是否重複入庫、是否改錯舊資料與是否觸發錯誤彙總。
建立四格版本矩陣:舊檔對舊匯入器、舊檔對新匯入器、新檔對舊匯入器、新檔對新匯入器。逐格定義支援、拒絕或需轉換,不要求所有組合一定相容,但要求行為可預測。已停用的組合也要確認不會被排程意外使用。
除了正常資料,放入零值、負值、空欄、長文字、中文、帶換行備註與邊界數值。新增欄若有逗號或引號,可能連帶破壞舊的簡單split解析器。這是解析器能力問題,不能要求操作員永遠不要輸入正常的備註符號。
分版本發布並驗證回退
正式發布採可辨識的結構版本,可以放在受控檔名、旁附清冊或正式欄位中。不要隨意在CSV第一行加一段版本說明文字,除非所有接收者都已約定跳過它,否則原來的標題列會被移到第二行而再次破壞格式。
若需要過渡期間同時產出兩版,使用不同交接位置或明確版本識別,防止下游把同一事件兩版都匯入。必要時以轉換器輸出舊契約,但轉換器也要有自己的測試與版本;移除新欄不代表所有新語意都能安全降版。
失敗時先查下游讀的是哪個實際檔案與版本,再查位置或名稱映射、預設值與型別轉換。若匯入成功但總量變小,核對數量是否讀到品質代碼;若只有中文欄失敗,查編碼與BOM,不要先改資料庫數值型別。
回退也要測:新匯入器已接受新版檔後,舊版是否還能處理待送檔與既有資料?若不能,回退計畫要保留轉換或排空策略。驗收保存輸入檔、解析後欄位、入庫結果與版本矩陣,讓相容性結論有可重播的證據。
測試結果要保存解析後的欄位名稱和值,而不是只留成功訊息。若下游不提供明細,就以可回查的測試事件核對入庫結果;無法觀察最終值的組合應標為尚未驗證,不能依其他版本的成功推定通過。
練習與常見問題
練習:舊檔欄序為編號、數量,新增單位放在兩欄中間。資料A01、pcs、12送入舊位置程式時,應明確拒絕或經已驗證轉換後得到數量12;若程式把pcs轉失敗後默默補零,應判驗收失敗,不是成功匯入零件數。
問:只新增欄位一定向後相容嗎?答:取決於接收者映射、欄數與未知欄處理,必須逐版測試。
問:用欄名就不用管順序嗎?答:仍須確認實際工具按欄名映射,並檢查重名、缺名與語意。
問:缺少品質欄可預設良好嗎?答:除非契約有足夠依據,否則應保留未知或拒絕。
問:新舊檔都匯入成功就完成嗎?答:還要核對每欄值、唯一事件數與下游彙總,避免成功但讀錯。
參考:Python csv:DictReader及欄位解析行為。
參考:PostgreSQL 18 COPY:指定目標欄位與檔案匯入選項。