Hướng dẫn Giải quyết Xung đột Migration trong Prisma
Đừng chạy prisma migrate reset trên cơ sở dữ liệu production.
Nếu bạn thấy thông báo rằng một migration đã bị sửa đổi hoặc bạn cần reset schema, hãy dừng lại. Việc reset sẽ xóa toàn bộ dữ liệu của bạn. Bạn có thể khắc phục các xung đột này một cách thủ công mà không làm mất bất kỳ dữ liệu nào.
Các lỗi Prisma thường gặp và cách khắc phục
Lỗi: Migration thất bại giữa chừng (P3018)
• Sửa tệp SQL.
• Chạy: npx prisma migrate resolve --rolled-back [migration_name]
• Chạy: npx prisma db execute --file [path_to_sql_file]
• Chạy: npx prisma migrate resolve --applied [migration_name]
Lỗi: Migration bị sửa đổi sau khi đã áp dụng (Sai lệch Checksum)
• Tính toán mã băm SHA-256 của tệp migration hiện tại của bạn.
• Cập nhật checksum trong bảng _prisma_migrations.
• Quan trọng: Cập nhật tất cả các hàng cho tên migration đó. Đừng lọc theo rolled_back_at.
Lỗi: Thiếu cột trong shadow database (P3006) • Điều này xảy ra khi một migration tham chiếu đến một cột mà một migration sau đó mới tạo ra. • Prisma thực hiện lại (replay) các migration theo thứ tự thời gian (timestamp). • Cách khắc phục: Di chuyển mã SQL đến migration nơi cột đó được tạo ra lần đầu tiên.
Lỗi: Lệnh DROP COLUMN bị chặn bởi chính sách RLS
• Row Level Security của PostgreSQL gắn kết các chính sách với các cột.
• Cách khắc phục: Sử dụng CASCADE khi xóa các cột.
• Ví dụ: ALTER TABLE "my_table" DROP COLUMN IF EXISTS "tenant_id" CASCADE;
Các phương pháp hay nhất để Migration an toàn
- Truy vấn cơ sở dữ liệu trước. Đừng đoán xem một cột hoặc index có tồn tại hay không. Hãy sử dụng các truy vấn SQL trực tiếp để kiểm tra schema thực tế của cơ sở dữ liệu trước khi viết mã migration.
- Sử dụng
IF EXISTSvàIF NOT EXISTS. Điều này giúp các migration của bạn có tính idempotent (có thể thực hiện nhiều lần mà không thay đổi kết quả sau lần đầu). Một migration idempotent có thể chạy nhiều lần mà không gây ra lỗi. - Sử dụng các khối
DOcho các ràng buộc (constraints). Bao bọc việc thêm Foreign Key trong một bước kiểm tra xem tên ràng buộc đã tồn tại hay chưa. - Luôn sử dụng
CASCADEkhi xóa (drop) nếu bạn sử dụng Row Level Security.
Bảng tóm tắt
• P3018 (Thất bại giữa chừng): Sửa SQL, sau đó sử dụng resolve --rolled-back và resolve --applied.
• Sai lệch checksum: Tính toán mã băm mới và cập nhật tất cả các hàng trong _prisma_migrations.
• Lỗi Shadow DB: Kiểm tra thứ tự timestamp và di chuyển logic SQL.
• Lỗi RLS: Thêm CASCADE vào các câu lệnh DROP của bạn.
