Mengembalikan teks biasa pg_dump dengan psql dan --disable-trigger

8

Saya harus melakukan beberapa tes dengan skrip pendek untuk memperbarui beberapa data "lawas" di salah satu tabel saya.

Berhati-hati karena saya, menggunakan skrip yang belum diuji, saya memutuskan untuk membuat cadangan tabel yang relevan sebelum melakukannya. Cara termudah untuk melakukannya adalah:

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

Sekarang saya melakukan apa yang harus saya lakukan, memeriksa hasilnya dan merasa hasilnya tidak memuaskan. Saya berpikir dalam hati: betapa beruntungnya saya memiliki cadangan meja itu.

Saya sudah diperingatkan ketika saya mencadangkan meja bahwa:

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.

Saya tidak terlalu memikirkannya, tetapi sekarang kami memiliki masalah. Memang tabel tersebut memiliki beberapa pemicu yang melekat padanya, tapi saya tidak bisa mengembalikan table.sqlopsi with dengan --disable-triggers perintah pg_restore.

Jika saya mencoba mengikuti perintah saya mendapat pesan kesalahan:

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

yaitu:

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

Apakah ada bendera untuk psqlperintah-yang menunjukkan perilaku yang sama --disable-triggers?

Saya telah memeriksa psql "manpage" , mencari pemicu dan kata kunci serupa tetapi tidak menemukan apa pun.

Atau satu-satunya pilihan saya harus menjatuhkan pemicu di atas meja sebelum mengembalikan data?

Sidenote: Saya menggunakan postgres v. 9.3 pada Sistem Ubuntu 14.10


Disarankan untuk mengedit file sql yang dihasilkan, untuk memasukkan pernyataan:

ALTER TABLE table DISABLE TRIGGER ALL

Ketika saya sekarang dieksekusi: psql -d database -f table.sqlSaya mendapat pesan kesalahan tentang melanggar batasan "Unik" dari kunci utama.

Untuk memperbaiki ini saya mencoba untuk membungkus salinan ke:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Sekarang pesan kesalahannya adalah:

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

Peringatan terakhir berulang untuk masing-masing \N(melambangkan nilai nol) di dump.

Vogel612
sumber
2
Anda dapat pergi dan mengedit dump Anda di editor apa pun. Hanya menambahkan COPYdengan ALTER TABLE table DISABLE TRIGGER ALLdan mengaktifkan kembali ini di akhir.
dezso
Hanya bergantung pada penonaktifan, saya mendapatkan kesalahan yang menyatakan salinan melanggar batasan unik dari kunci utama. (Cukup bisa dimengerti) Ketika saya melanjutkan untuk BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;mengamankan data saya, saya dihujani pesan tentang perintah yang tidak valid :(
Vogel612
@ Vogel612 "perintah tidak valid"? Tolong tunjukkan kesalahan yang tepat.
Craig Ringer
@CraigRinger Maaf untuk menunggu, saya mengedit pertanyaan untuk memasukkan apa yang saya lakukan dan pesan kesalahan yang saya
terima
Semua ini berarti bahwa beberapa data telah diperbarui, bukan? Cobalah untuk memperbaruinya kembali, menggunakan tabel temp di mana Anda menyalin data asli.
dezso

Jawaban:

4

@dezso memiliki ide yang sepenuhnya benar :

Semua ini berarti bahwa beberapa data telah diperbarui, bukan? Coba perbarui kembali, menggunakan tabel temp di mana Anda menyalin data asli

Satu-satunya yang tersisa sekarang adalah mewujudkannya.

Jadi inilah yang saya lakukan. Saya mengambil daun dari bukunya dan secara manual mengedit file dump untuk menggunakan tabel bernama table_backup. Kemudian saya membuat tabel kata menggunakan definisi yang disediakan di pgAdmin saya (tetapi bisa juga dilakukan secara manual).

Saya meninggalkan pemicu dan kendala, serta Kunci Asing, dan kemudian melanjutkan untuk "memperbarui" tabel asli dengan data dari tabel cadangan seperti berikut:

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;

Jadi saya akhirnya kembali dengan data asli saya, siap untuk testrun berikutnya;)

Vogel612
sumber
0

Tambahkan baris ini ke dump data .sql:

set session_replication_role = replica;

dan psql seharusnya tidak mengeluh tentang pemulihan.

Ivan Kozik
sumber