Import dữ liệu hàng loạt vào PostgreSQL giống như chơi tetris vậy: mọi mảnh ghép (dữ liệu) phải khớp hoàn hảo với bảng hiện có (cấu trúc database). Nhưng cũng như trong game, lỗi xảy ra thường xuyên, có thể làm chậm quá trình hoặc thậm chí làm sập luôn. Bạn có thể gặp vấn đề về không khớp kiểu dữ liệu, encoding, dữ liệu trùng lặp, hoặc đôi khi là lỗi quyền truy cập bất ngờ.
Vậy cụ thể có những lỗi gì, làm sao để phát hiện và phòng tránh? Hôm nay tụi mình sẽ phân tích kỹ các vấn đề thường gặp nhất, để bạn trở thành pro trong việc import dữ liệu hàng loạt nhé.
Lỗi không khớp cấu trúc dữ liệu
Vấn đề với kiểu dữ liệu
Rất thường xuyên khi import dữ liệu bạn sẽ thấy lỗi kiểu như:
ERROR: cú pháp đầu vào không hợp lệ cho kiểu integer: "abc"
CONTEXT: COPY students, dòng 3, cột age: "abc"
Chuyện này xảy ra khi dữ liệu trong file CSV của bạn không đúng với kiểu dữ liệu mong đợi của cột. Ví dụ, cột age mong đợi là số, nhưng dữ liệu lại là chuỗi "abc". PostgreSQL không biết chuyển text thành số kiểu gì nên quá trình import bị dừng lại.
Làm sao tránh?
- Kiểm tra file CSV trước khi import. Nếu dùng Excel hoặc Python, nhớ đảm bảo mọi cột đúng kiểu dữ liệu mong muốn.
- Nếu vẫn bị lỗi, bạn có thể thử import vào bảng tạm với tất cả các cột kiểu
TEXT, rồi sau đó chuyển đổi kiểu dữ liệu:
UPDATE temp_students
SET age = CAST(age AS INTEGER)
WHERE age ~ '^\d+$';
Thiếu cột
Nếu cấu trúc bảng không khớp với dữ liệu trong file CSV, PostgreSQL sẽ báo lỗi. Ví dụ:
ERROR: thiếu dữ liệu cho cột "email"
CONTEXT: COPY students, dòng 2: "John,Doe,21"
Thường là do header (hoặc thứ tự cột) trong file CSV khác với cấu trúc bảng.
Làm sao tránh? Khi dùng lệnh COPY hãy luôn truyền danh sách các cột bạn muốn điền dữ liệu:
COPY students (first_name, last_name, age)
FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER;
Lỗi encoding
Vấn đề với các encoding khác nhau
Nếu file CSV của bạn được lưu với encoding khác UTF-8 (ví dụ Windows-1251), PostgreSQL có thể không đọc được file. Điều này gây lỗi, nhất là khi dữ liệu có ký tự Cyrillic:
ERROR: chuỗi byte không hợp lệ cho encoding "UTF8": 0xd0
CONTEXT: COPY students, dòng 1
Làm sao tránh?
- Đảm bảo file CSV của bạn được lưu bằng UTF-8.
- Nếu không thể, hãy chỉ định encoding khi import:
COPY students FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER
ENCODING 'WIN1251';
Lỗi truy cập file
Vấn đề với quyền truy cập
Nếu bạn dùng lệnh COPY, PostgreSQL phải có quyền truy cập file bạn đang import. Nếu file không truy cập được, bạn sẽ thấy lỗi:
ERROR: không thể mở file "/path/to/file.csv" để đọc: Permission denied
Hoặc thậm chí:
ERROR: không tồn tại file hoặc thư mục
Làm sao tránh?
- Đảm bảo PostgreSQL có quyền truy cập file. Trên Linux có thể do quyền file. Dùng lệnh
chmodđể cấp quyền:chmod 644 /path/to/file.csv - Nếu bạn làm việc trên máy cá nhân, hãy dùng lệnh
\COPYthay vìCOPY.
Vấn đề với dữ liệu trùng lặp
Khi import dữ liệu vào bảng có ràng buộc UNIQUE (ví dụ id duy nhất), bạn có thể gặp lỗi xung đột:
ERROR: giá trị key trùng lặp vi phạm ràng buộc unique "students_pkey"
DETAIL: Key (id)=(1) đã tồn tại.
Chuyện này xảy ra khi file CSV có dòng trùng hoặc dữ liệu đã có sẵn trong bảng.
Làm sao tránh?
- Dùng option
ON CONFLICTđể xử lý giá trị trùng:INSERT INTO students (id, first_name, last_name) VALUES (1, 'John', 'Doe') ON CONFLICT (id) DO NOTHING;
- Nếu bạn dùng
COPYhoặc\COPY, hãy import tạm vào bảng trung gian rồi insert vào bảng chính với xử lý trùng lặp.
Lỗi giá trị rỗng
Trong PostgreSQL, các cột có ràng buộc NOT NULL không cho phép giá trị rỗng. Nếu file CSV của bạn có cột bị rỗng, bạn sẽ thấy lỗi:
ERROR: giá trị null trong cột "email" vi phạm ràng buộc not-null
Làm sao tránh?
- Đảm bảo file CSV có giá trị cho tất cả các cột bắt buộc.
- Nếu cho phép giá trị rỗng, hãy bỏ ràng buộc
NOT NULLhoặc đặt giá trị mặc định:
ALTER TABLE students ALTER COLUMN email SET DEFAULT 'unknown@example.com';
Lỗi khi log
Không có thông tin lỗi
Nếu bạn import file lớn, việc lưu lại thông tin lỗi là rất quan trọng. Tiếc là lệnh COPY mặc định không có cơ chế log lỗi.
Làm sao tránh? Hãy cấu hình log lỗi bằng một bảng riêng. Ví dụ, tạo bảng log lỗi và chuyển các dòng lỗi vào đó:
COPY students FROM '/path/to/file.csv'
DELIMITER ','
CSV HEADER
LOG ERRORS INTO error_log
REJECT LIMIT 100;
Tóm tắt cách phòng tránh lỗi
- Luôn phân tích và kiểm tra dữ liệu trước khi import.
- Dùng bảng tạm để xử lý dữ liệu trước.
- Bật log lỗi và phân tích chúng.
- Nếu có xung đột hoặc không khớp, dùng
ON CONFLICThoặc import vào bảng trung gian. - Kiểm tra encoding file và cấu hình server.
Import dữ liệu hàng loạt có thể khá khoai, nhưng nếu làm đúng cách thì bạn sẽ thấy quá trình này nhanh, ổn định và hiệu quả. Muốn thử kỹ năng mới học không? Hãy thử import một file CSV lớn vào database test và kiểm tra xem mọi dữ liệu đã lên đúng chưa nhé!
GO TO FULL VERSION