Khôi phục pg_dump văn bản đơn giản với psql và --disable-trigger


8

Tôi đã phải thực hiện một số thử nghiệm với một đoạn script ngắn để cập nhật một số dữ liệu "di sản" trong một trong các bảng của mình.

Thận trọng như tôi, sử dụng một tập lệnh chưa được kiểm tra, tôi quyết định sao lưu bảng có liên quan trước khi thực hiện. Cách đơn giản nhất để làm điều đó là:

pg_dump -a --file table.sql -t table database

Bây giờ tôi đã làm những gì tôi phải làm, kiểm tra kết quả và thấy chúng không đạt yêu cầu. Tôi tự nghĩ: mình thật may mắn khi có một bản sao lưu của cái bàn đó.

Tôi đã được cảnh báo khi tôi sao lưu bảng rằng:

pg_dump: NOTICE: there are circular foreign-key constraints among these table(s):
pg_dump:   table
pg_dump: You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
pg_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.

Tôi đã không nghĩ nhiều về nó, nhưng bây giờ chúng tôi có một vấn đề. Thật vậy, bảng trong câu hỏi có nhiều kích hoạt được đính kèm, nhưng tôi không thể khôi phục table.sqltùy chọn với --disable-triggers lệnh pg_restore.

Nếu tôi thử làm theo lệnh tôi nhận được thông báo lỗi:

pg_restore -a -d database -t table -h localhost --disable-triggers table.sql

cụ thể là:

pg_restore: [archiver] input file appears to be a text format dump. Please use psql.

Có một lá cờ cho psql-command thể hiện hành vi tương tự như --disable-triggers?

Tôi đã kiểm tra "manpage" psql , tìm kiếm kích hoạt và các từ khóa tương tự nhưng không tìm thấy gì.

Hoặc là tùy chọn duy nhất tôi phải bỏ các kích hoạt trên bảng trước khi khôi phục dữ liệu?

Sidenote: Tôi đang sử dụng postgres v. 9.3 trên Hệ thống Ubuntu 14.10


Nó được đề xuất để chỉnh sửa tệp sql được tạo, để bao gồm câu lệnh:

ALTER TABLE table DISABLE TRIGGER ALL

Khi tôi thực thi: psql -d database -f table.sqlTôi nhận được một thông báo lỗi về việc vi phạm ràng buộc "Duy nhất" của khóa chính.

Để khắc phục điều này, tôi đã cố gắng bọc bản sao vào:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Bây giờ thông báo lỗi là:

psql:project_backup.sql:18: ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL:  Table "another" references "table".
HINT:  Truncate table "another" at the same time, or use TRUNCATE ... CASCADE.
psql:project_backup.sql:20: ERROR:  current transaction is aborted, commands ignored until end of transaction block
psql:project_backup.sql:21: invalid command \N
psql:project_backup.sql:22: invalid command \N

Cảnh báo sau lặp lại cho mỗi \N(tượng trưng cho giá trị null) trong kết xuất.


2
Bạn có thể đi và chỉnh sửa kết xuất của bạn trong bất kỳ trình soạn thảo. Chỉ cần chuẩn bị trước COPYvới một ALTER TABLE table DISABLE TRIGGER ALLvà có thể nhận được những thứ này vào cuối.
dezso

Chỉ chuẩn bị vô hiệu hóa, tôi nhận được một lỗi cho biết bản sao vi phạm ràng buộc duy nhất của khóa chính. (Khá dễ hiểu) Khi tôi tiến hành BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;bảo mật dữ liệu của mình, tôi nhận được thông báo về các lệnh không hợp lệ :(
Vogel612

@ Vogel612 "lệnh không hợp lệ"? Hiển thị các lỗi chính xác xin vui lòng.
Craig Ringer

@CraigRinger Xin lỗi vì đã chờ đợi, tôi đã chỉnh sửa câu hỏi để bao gồm những gì tôi đã làm và các thông báo lỗi tôi nhận được
Vogel612

Tất cả điều này có nghĩa là một số dữ liệu đã được cập nhật, phải không? Cố gắng cập nhật chúng trở lại, sử dụng bảng tạm thời nơi bạn sao chép dữ liệu gốc.
dezso

Câu trả lời:


4

@dezso đã có ý tưởng hoàn toàn đúng :

Tất cả điều này có nghĩa là một số dữ liệu đã được cập nhật, phải không? Cố gắng cập nhật chúng trở lại, sử dụng bảng tạm thời nơi bạn sao chép dữ liệu gốc

Điều duy nhất còn lại bây giờ là làm cho nó xảy ra.

Vì vậy, đây là những gì tôi đã làm. Tôi lấy một chiếc lá ra khỏi cuốn sách của anh ấy và chỉnh sửa thủ công tệp kết xuất để sử dụng bảng có tên table_backup. Sau đó, tôi đã tạo bảng cho biết bằng cách sử dụng định nghĩa được cung cấp trong pgAdmin của tôi (nhưng nó cũng có thể được thực hiện thủ công).

Tôi đã bỏ qua các kích hoạt và ràng buộc, cũng như Khóa ngoài và sau đó tiến hành "cập nhật" bảng gốc với dữ liệu từ bảng sao lưu như sau:

BEGIN TRANSACTION;
ALTER TABLE table DISABLE TRIGGER ALL;

UPDATE table SET 
    (column1, column2, ...) = 
    (table_backup.column1, table_backup.colum2, ...)
FROM table_backup WHERE table.pk_column = table_backup.pk_column;

ALTER TABLE table ENABLE TRIGGER ALL;
-- I didn't but you can drop table_backup here
COMMIT;

Vì vậy, cuối cùng tôi đã trở lại với dữ liệu gốc của mình, sẵn sàng cho lần thử nghiệm tiếp theo;)


0

Chuẩn bị dòng này vào kết xuất dữ liệu .sql:

set session_replication_role = replica;

và psql không nên phàn nàn về việc khôi phục.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.