在 PostgreSQL 裡批量匯入資料就像在玩俄羅斯方塊:每個小方塊(資料)都要剛好塞進現有的表格(資料庫結構)裡。但就像打電動一樣,常常會出現各種錯誤,可能會拖慢進度,甚至直接 GG。你可能會遇到資料型別不符、編碼問題、重複資料,甚至還有權限相關的奇怪錯誤。
到底會有哪些錯誤?怎麼發現、怎麼避免?今天我們就來細聊這些最常見的問題,讓你也能變成批量匯入資料的高手!
資料結構不符的錯誤
資料型別的問題
很常在匯入資料時你會看到像這樣的錯誤:
ERROR: 輸入語法無效,預期型別 integer: "abc"
CONTEXT: COPY 學生, 第3行, 欄位 年齡: "abc"
這種情況通常是你的 CSV 檔案裡的資料型別跟資料表預期的不一樣。比如 age 欄位本來要數字,結果資料裡卻是 "abc" 這種字串。PostgreSQL 不知道怎麼把文字轉成數字,匯入就直接中斷了。
怎麼避免?
- 匯入前先檢查你的 CSV 檔案。如果你用 Excel 或 Python 處理,記得每個欄位都要對應正確的型別。
- 如果還是有錯,可以先把資料匯到一個所有欄位都是
TEXT的暫存表,然後再轉型別:
UPDATE temp_students
SET age = CAST(age AS INTEGER)
WHERE age ~ '^\d+$';
缺少欄位
如果資料表的結構跟 CSV 檔案不一樣,PostgreSQL 會報錯。例如:
ERROR: 欄位 "email" 缺少資料
CONTEXT: COPY 學生, 第2行: "John,Doe,21"
這通常是因為 CSV 檔案的標題(或欄位順序)跟資料表不一樣。
怎麼避免? 用 COPY 指令時,記得指定你要填的欄位:
COPY students (first_name, last_name, age)
FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER;
編碼錯誤
不同編碼的問題
如果你的 CSV 檔案不是用 UTF-8 存的(比如 Windows-1251),PostgreSQL 可能會看不懂,尤其裡面有俄文或其他特殊字元時會直接報錯:
ERROR: 編碼 "UTF8" 的位元組序列無效: 0xd0
CONTEXT: COPY 學生, 第1行
怎麼避免?
- 確認你的 CSV 檔案是用 UTF-8 編碼。
- 如果真的沒辦法,匯入時指定檔案的編碼:
COPY students FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER
ENCODING 'WIN1251';
檔案存取權限錯誤
權限不足的問題
用 COPY 指令時,PostgreSQL 必須能存取你要匯入的檔案。如果檔案沒權限,會看到這種錯誤:
ERROR: 無法開啟檔案 "/path/to/file.csv" 讀取: 權限被拒絕
或甚至:
ERROR: 找不到檔案或目錄
怎麼避免?
- 確認 PostgreSQL 有權限存取檔案。在 Linux 下通常是權限問題。用
chmod指令開權限:chmod 644 /path/to/file.csv - 如果你是在自己電腦上操作,用
\COPY,不要用COPY。
重複資料的問題
如果你要匯入的資料表有 UNIQUE 限制(像是唯一識別碼),遇到重複資料就會報錯:
ERROR: 重複的鍵值違反唯一限制 "students_pkey"
DETAIL: 鍵 (id)=(1) 已經存在。
這通常是 CSV 檔案裡有重複資料,或資料表裡已經有這些資料了。
怎麼避免?
- 用
ON CONFLICT處理重複值:INSERT INTO students (id, first_name, last_name) VALUES (1, 'John', 'Doe') ON CONFLICT (id) DO NOTHING;
- 如果你用
COPY或\COPY,可以先匯到暫存表,再處理重複資料後插入主表。
空值錯誤
在 PostgreSQL 裡,設了 NOT NULL 限制的欄位不能有空值。如果你的 CSV 檔案有空欄位,會看到這種錯誤:
ERROR: 欄位 "email" 的值為 null 違反 not-null 限制
怎麼避免?
- 確認 CSV 檔案裡所有必填欄位都有值。
- 如果允許空值,可以移除
NOT NULL限制,或設個預設值:
ALTER TABLE students ALTER COLUMN email SET DEFAULT 'unknown@example.com';
日誌記錄錯誤
沒有錯誤資訊
如果你在匯入大檔案,記錄錯誤資訊很重要。可惜 COPY 預設沒提供錯誤日誌的功能。
怎麼避免? 可以自己設一個錯誤日誌表,把有問題的資料丟進去:
COPY students FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER
LOG ERRORS INTO error_log
REJECT LIMIT 100;
避免錯誤的總結
- 匯入前一定要先分析、檢查資料。
- 用暫存表先處理資料再正式匯入。
- 開啟錯誤日誌,記得檢查錯誤。
- 遇到衝突或不符時,用
ON CONFLICT或暫存表處理。 - 檢查檔案編碼,設定好伺服器參數。
批量匯入資料其實不簡單,但只要方法對,這流程就會又快又穩又有效率。想試試你的新技能嗎?找個大一點的 CSV 檔案,丟進測試資料庫,看看資料是不是都正確進去了!
GO TO FULL VERSION