Catatan: jawaban saya benar-benar menghapus tabel dan objek database lainnya; untuk menghapus semua data dalam tabel, yaitu memotong semua tabel , Endre Both telah memberikan pernyataan yang sama dieksekusi dengan baik (eksekusi langsung) sebulan kemudian.
Untuk kasus di mana Anda tidak bisa hanya DROP SCHEMA public CASCADE;
, DROP OWNED BY current_user;
atau sesuatu, berikut ini skrip SQL yang berdiri sendiri yang saya tulis, yang aman untuk transaksi (yaitu Anda dapat meletakkannya di antara BEGIN;
dan baik ROLLBACK;
untuk mengujinya atau COMMIT;
benar-benar melakukan perbuatan) dan membersihkan "semua" objek database ... yah, semua yang digunakan dalam database yang digunakan aplikasi kita atau yang bisa saya tambahkan dengan bijak, yaitu:
- pemicu di tabel
- kendala pada tabel (FK, PK
CHECK
,, UNIQUE
)
- indikasi
VIEW
s (normal atau terwujud)
- tabel
- urutan
- rutinitas (fungsi agregat, fungsi, prosedur)
- semua nōn-default (yaitu bukan
public
atau DB-internal) skema “kami” sendiri: skrip berguna ketika dijalankan sebagai “bukan superuser database”; superuser dapat menghapus semua skema (yang sangat penting masih secara eksplisit dikecualikan)
- ekstensi (kontribusi pengguna tetapi saya biasanya sengaja membiarkannya)
Tidak dijatuhkan (beberapa disengaja; beberapa hanya karena saya tidak punya contoh di DB kami):
- yang
public
skema (misalnya untuk hal-hal ekstensi yang disediakan di dalamnya)
- collations dan barang lokal lainnya
- pemicu acara
- penelusuran teks,… (lihat di sini untuk hal-hal lain yang mungkin saya lewatkan)
- peran atau pengaturan keamanan lainnya
- jenis komposit
- tabel roti panggang
- PLRT Asing dan tabel asing
Ini sangat berguna untuk kasus-kasus ketika dump yang ingin Anda pulihkan adalah versi skema database yang berbeda (misalnya dengan Debian dbconfig-common
, Flyway atau Liquibase / DB-Manul) daripada database tempat Anda ingin mengembalikannya.
Saya juga mendapat versi yang menghapus "semua kecuali dua tabel dan apa yang menjadi miliknya" (urutan, diuji secara manual, maaf, saya tahu, membosankan) jika ada yang tertarik; perbedaannya kecil. Hubungi saya atau periksa repo ini jika tertarik.
SQL
DO $$
DECLARE
q TEXT;
r RECORD;
BEGIN
FOR r IN (SELECT pns.nspname, pc.relname, pt.tgname
FROM pg_catalog.pg_trigger pt, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pt.tgrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pt.tgisinternal=false
) LOOP
EXECUTE format('DROP TRIGGER %I ON %I.%I;',
r.tgname, r.nspname, r.relname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pcon.contype='f'
) LOOP
EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
r.nspname, r.relname, r.conname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pcon.contype<>'f'
) LOOP
EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
r.nspname, r.relname, r.conname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='i'
) LOOP
EXECUTE format('DROP INDEX %I.%I;',
r.nspname, r.relname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind IN ('v', 'm')
) LOOP
EXECUTE format('DROP VIEW %I.%I;',
r.nspname, r.relname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='r'
) LOOP
EXECUTE format('DROP TABLE %I.%I;',
r.nspname, r.relname);
END LOOP;
FOR r IN (SELECT pns.nspname, pc.relname
FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
WHERE pns.oid=pc.relnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pc.relkind='S'
) LOOP
EXECUTE format('DROP SEQUENCE %I.%I;',
r.nspname, r.relname);
END LOOP;
FOR r IN (SELECT pns.nspname, pe.extname
FROM pg_catalog.pg_extension pe, pg_catalog.pg_namespace pns
WHERE pns.oid=pe.extnamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
) LOOP
EXECUTE format('DROP EXTENSION %I;', r.extname);
END LOOP;
FOR r IN (SELECT pns.nspname, pp.proname, pp.oid
FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns, pg_catalog.pg_aggregate pagg
WHERE pns.oid=pp.pronamespace
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
AND pagg.aggfnoid=pp.oid
) LOOP
EXECUTE format('DROP AGGREGATE %I.%I(%s);',
r.nspname, r.proname,
pg_get_function_identity_arguments(r.oid));
END LOOP;
IF EXISTS (SELECT * FROM pg_catalog.pg_attribute
WHERE attrelid='pg_catalog.pg_proc'::regclass
AND attname='prokind'
) THEN
q := 'CASE pp.prokind
WHEN ''p'' THEN ''PROCEDURE''
WHEN ''a'' THEN ''AGGREGATE''
ELSE ''FUNCTION''
END';
ELSIF EXISTS (SELECT * FROM pg_catalog.pg_attribute
WHERE attrelid='pg_catalog.pg_proc'::regclass
AND attname='proisagg'
) THEN
q := 'CASE pp.proisagg
WHEN true THEN ''AGGREGATE''
ELSE ''FUNCTION''
END';
ELSE
q := '''FUNCTION''';
END IF;
FOR r IN EXECUTE 'SELECT pns.nspname, pp.proname, pp.oid, ' || q || ' AS pt
FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns
WHERE pns.oid=pp.pronamespace
AND pns.nspname NOT IN (''information_schema'', ''pg_catalog'', ''pg_toast'')
' LOOP
EXECUTE format('DROP %s %I.%I(%s);', r.pt,
r.nspname, r.proname,
pg_get_function_identity_arguments(r.oid));
END LOOP;
FOR r IN (SELECT pns.nspname
FROM pg_catalog.pg_namespace pns, pg_catalog.pg_roles pr
WHERE pr.oid=pns.nspowner
AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast', 'public')
AND pr.rolname=current_user
) LOOP
EXECUTE format('DROP SCHEMA %I;', r.nspname);
END LOOP;
RAISE NOTICE 'Database cleared!';
END; $$;
Diuji, kecuali tambahan selanjutnya ( extensions
disumbangkan oleh Clément Prévost ), di PostgreSQL 9.6 ( jessie-backports
). Penghilangan agregat diuji pada 9.6 dan 12.2, prosedur penghilangan juga diuji pada 12.2. Perbaikan bug dan peningkatan lebih lanjut diterima!
dbname='db_name' && dropdb $dbname && createdb $dbname && psql -d $dbname -f dump.sql