PostgreSQL: jatuhkan kolom dari tampilan

10

Saya mempunyai VIEWtempat untuk mencoba membuat skrip evolusi, sehingga saya dapat menambahkan kolom ke dalamnya. Bagian itu berfungsi dengan baik; kolom ditambahkan dengan baik. Namun, kebalikannya tidak bekerja; hapus kolom yang terakhir ditambahkan gagal dengan ERROR: cannot drop columns from viewpesan. Masalahnya adalah bahwa pandangan khusus ini memiliki banyak referensi, baik dari dan ke, oleh karena itu saya tidak bisa begitu DROP CASCADEsaja!

Apakah ada alasan mengapa saya tidak dapat menghapus kolom yang baru ditambahkan dari yang diberikan VIEW? Lalu, apa yang bisa saya lakukan untuk menyelesaikan tugas ini?

(Catatan: keadaannya, di sini, adalah apa adanya, tapi saya bisa melihat situasi yang sama, alias menjatuhkan kolom dari tampilan, dalam banyak kasus lain.)

Yanick Rochon
sumber
Bagaimana Anda menambahkan kolom pada awalnya? Anda tidak bisa ALTER VIEW ... ADD COLUMN. Apakah Anda menggunakan CREATE OR REPLACE VIEW? Tolong tunjukkan kode Anda .
Craig Ringer
@CraigRinger, ya, CREATE OR REPLACE VIEWdengan def yang sama, kecuali kolom tambahan (karena tabel ref'ed memiliki kolom baru ditambahkan, jadi pandangan harus memasukkannya). "Devolution" menghapus kolom dari tabel yang ditolak, sehingga VIEWharus juga tidak mengembalikannya lagi.
Yanick Rochon

Jawaban:

13

PostgreSQL (true hingga setidaknya 9,4) saat ini tidak mendukung penghapusan kolom dengan CREATE OR REPLACE VIEW.

Kueri baru harus menghasilkan kolom yang sama dengan yang dihasilkan oleh permintaan tampilan yang ada (yaitu, nama kolom yang sama dalam urutan yang sama dan dengan tipe data yang sama), tetapi itu dapat menambahkan kolom tambahan ke akhir daftar.

Tidak ada alasan mendasar mengapa dukungan untuk menjatuhkan kolom tidak dapat ditambahkan, tetapi belum ada yang melakukan pekerjaan yang diperlukan untuk mengimplementasikannya.

CREATE OR REPLACE VIEWharus memindai semua dependensi secara rekursif dan memastikan bahwa tidak ada yang mereferensikan kolom yang akan dihapus. Jika mereka menggunakan SELECT *itu harus menghapus kolom dari ekspansi *di ketergantungan kemudian memindai nya dependensi juga. Ada sedikit pekerjaan yang terlibat dalam melakukan itu, dan ada beberapa area di mana tidak jelas bagaimana tepatnya menjatuhkan kolom harus berperilaku terutama ketika datang ke interaksi dengan dump dan memuat ulang. Jadi belum ada yang menginginkan fitur yang cukup untuk mengimplementasikannya. Tambalan dan / atau sponsor pembangunan dipersilakan.

Anda harus membuang tampilan dan segala sesuatu yang bergantung padanya, lalu membuatnya kembali dan dependensinya. (Hal yang sama berlaku untuk menambahkan kolom ke tampilan; dukungan untuk menambahkan kolom diperkenalkan pada 8.4).

Perhatikan bahwa secara umum tidak ada harapan bahwa DDL dapat dibalik. Konsep "devolusi" benar-benar cacat. Misalnya, jika Anda menjatuhkan kolom, lalu menambahkannya lagi, data masih hilang.

Craig Ringer
sumber
1
Jadi, apa yang Anda katakan adalah bahwa, setiap kali aplikasi besar dengan hubungan kompleks perlu mengubah kolom, itu perlu untuk membuat ulang seluruh (atau setidaknya sebagian besar) DDL? Saya tidak punya banyak pengalaman dengan postgre, tetapi berasal dari mySQL, saya tidak pernah mengalami masalah seperti itu (dengan Oracle, SQL Server atau MySQL), dan sepertinya aneh bagi saya bahwa perubahan tidak bisa begitu saja dilakukan dan kesalahan (jika any) dibuang pada waktu eksekusi. Keterbatasan ini cukup membatasi.
Yanick Rochon
@YanickRochon Yap, ini menyebalkan, dan saya ingin melihatnya membaik. Jika Anda ingin membantu mewujudkannya, pertimbangkan untuk mengerjakannya; lihat postgresql.org/support/professional_support .
Craig Ringer
Kami terlalu kecil untuk mendanai perusahaan semacam itu. Tapi senang melihatnya bukan topik yang pasti.
Yanick Rochon
1
@YanickRochon Cukup adil. Ada di TODO - "izinkan kompilasi tampilan / aturan ketika tabel yang mendasarinya berubah", wiki.postgresql.org/wiki/Todo#Views_and_Rules .
Craig Ringer