Saya sedang menulis skrip shell (akan menjadi cronjob) yang akan:
1: buang database produksi saya
2: impor dump ke database pengembangan saya
Antara langkah 1 dan 2, saya perlu menghapus database pengembangan (menghapus semua tabel?). Bagaimana ini paling baik dicapai dari skrip shell? Sejauh ini, tampilannya seperti ini:
#!/bin/bash
time=`date '+%Y'-'%m'-'%d'`
# 1. export(dump) the current production database
pg_dump -U production_db_name > /backup/dir/backup-${time}.sql
# missing step: drop all tables from development database so it can be re-populated
# 2. load the backup into the development database
psql -U development_db_name < backup/dir/backup-${time}.sql
database
backup
postgresql
Hoff
sumber
sumber
dbname='db_name' && dropdb $dbname && createdb $dbname && psql -d $dbname -f dump.sql
Jawaban:
Saya hanya akan menjatuhkan database dan kemudian membuatnya kembali. Pada sistem UNIX atau Linux, itu harus dilakukan:
Begitulah cara saya melakukannya.
sumber
createdb --owner=db_owner [--template=template0 --encoding=UTF8] db_name
saya menambahkan dua terakhir secara default ke semua databaseJika Anda tidak benar-benar membutuhkan cadangan database yang dibuang ke disk dalam format file skrip .sql teks biasa, Anda dapat menghubungkan
pg_dump
danpg_restore
langsung bersama-sama melalui pipa.Untuk melepaskan dan membuat ulang tabel, Anda dapat menggunakan
--clean
opsi baris perintah untukpg_dump
mengeluarkan perintah SQL untuk membersihkan (menjatuhkan) objek database sebelum (perintah untuk) membuatnya. (Ini tidak akan menghapus seluruh database, hanya setiap tabel / urutan / indeks / dll. Sebelum membuatnya kembali.)Dua di atas akan terlihat seperti ini:
pg_dump -U username --clean | pg_restore -U username
sumber
Meskipun baris berikut diambil dari skrip batch windows, perintahnya harus sangat mirip:
psql -U username -h localhost -d postgres -c "DROP DATABASE \"$DATABASE\";"
Perintah ini digunakan untuk menghapus seluruh database, dengan benar-benar menjatuhkannya. The
$DATABASE
(di Windows harus%DATABASE%
) dalam perintah adalah variabel lingkungan gaya windows yang mengevaluasi ke nama database. Anda harus menggantinya dengandevelopment_db_name
.sumber
dropdb
dan yang sudah tersediacreatedb
? Jika Anda dapat menjalankan psql, Anda juga dapat menjalankannya.Membuang:
Untuk memulihkan:
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U myuser -d my_db db/latest.dump
sumber
Jika Anda ingin membersihkan database Anda yang bernama "example_db":
1) Masuk ke db lain (misalnya 'postgres'):
2) Hapus database Anda:
DROP DATABASE example_db;
3) Buat kembali database Anda:
CREATE DATABASE example_db;
sumber
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 antaraBEGIN;
dan baikROLLBACK;
untuk mengujinya atauCOMMIT;
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:CHECK
,,UNIQUE
)VIEW
s (normal atau terwujud)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)Tidak dijatuhkan (beberapa disengaja; beberapa hanya karena saya tidak punya contoh di DB kami):
public
skema (misalnya untuk hal-hal ekstensi yang disediakan di dalamnya)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
-- Copyright © 2019, 2020 -- mirabilos <[email protected]> -- -- Provided that these terms and disclaimer and all copyright notices -- are retained or reproduced in an accompanying document, permission -- is granted to deal in this work without restriction, including un‐ -- limited rights to use, publicly perform, distribute, sell, modify, -- merge, give away, or sublicence. -- -- This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to -- the utmost extent permitted by applicable law, neither express nor -- implied; without malicious intent or gross negligence. In no event -- may a licensor, author or contributor be held liable for indirect, -- direct, other damage, loss, or other issues arising in any way out -- of dealing in the work, even if advised of the possibility of such -- damage or existence of a defect, except proven that it results out -- of said person’s immediate fault when using the work as intended. -- - -- Drop everything from the PostgreSQL database. DO $$ DECLARE q TEXT; r RECORD; BEGIN -- triggers 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; -- constraints #1: foreign key 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; -- constraints #2: the rest 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; -- indicēs 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; -- normal and materialised views 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; -- tables 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; -- sequences 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; -- extensions (only if necessary; keep them normally) 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; -- aggregate functions first (because they depend on other functions) 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; -- routines (functions, aggregate functions, procedures, window functions) IF EXISTS (SELECT * FROM pg_catalog.pg_attribute WHERE attrelid='pg_catalog.pg_proc'::regclass AND attname='prokind' -- PostgreSQL 11+ ) 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' -- PostgreSQL ≤10 ) 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; -- nōn-default schemata we own; assume to be run by a not-superuser 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; -- voilà 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!sumber
Saya telah menggunakan:
sumber