ฉันจะวางตารางทั้งหมดใน PostgreSQL ทำงานจากบรรทัดคำสั่งได้อย่างไร
ฉันไม่ต้องการวางฐานข้อมูลตัวเองเพียงตารางทั้งหมดและข้อมูลทั้งหมดในพวกเขา
public
คุณจะสูญเสียส่วนขยายที่ติดตั้งใด ๆ
ฉันจะวางตารางทั้งหมดใน PostgreSQL ทำงานจากบรรทัดคำสั่งได้อย่างไร
ฉันไม่ต้องการวางฐานข้อมูลตัวเองเพียงตารางทั้งหมดและข้อมูลทั้งหมดในพวกเขา
public
คุณจะสูญเสียส่วนขยายที่ติดตั้งใด ๆ
คำตอบ:
หากตารางทั้งหมดของคุณอยู่ในสคีมาวิธีการนี้อาจใช้งานได้ (ด้านล่างโค้ดจะถือว่าชื่อสคีมาของคุณคือpublic
)
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
หากคุณใช้ PostgreSQL 9.3 หรือสูงกว่าคุณอาจต้องกู้คืนค่าเริ่มต้น
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
pg_
) pg_catalog
ในขณะที่พวกเขาอยู่ในคีมาที่แตกต่างกัน
GRANT ALL ON SCHEMA public TO public;
หลังจากสร้าง
GRANT ALL
หลังจากการสร้าง?
คุณสามารถเขียนแบบสอบถามเพื่อสร้างสคริปต์ SQL ดังนี้:
select 'drop table "' || tablename || '" cascade;' from pg_tables;
หรือ:
select 'drop table if exists "' || tablename || '" cascade;' from pg_tables;
ในกรณีที่ตารางบางตารางถูกดร็อปโดยอัตโนมัติเนื่องจากตัวเลือกเรียงซ้อนในประโยคก่อนหน้า
นอกจากนี้ตามที่ระบุไว้ในความคิดเห็นคุณอาจต้องการกรองตารางที่คุณต้องการวางตามชื่อสคีมา:
select 'drop table if exists "' || tablename || '" cascade;'
from pg_tables
where schemaname = 'public'; -- or any other schema
จากนั้นเรียกใช้
COPY + PASTE อันทรงเกียรติจะทำงานเช่นกัน
drop schema public cascade;
แต่คุณเกือบจะมีสิทธิ์ในการวางตาราง
คำตอบที่ได้รับการยอมรับมากที่สุดในขณะที่เขียนนี้ (มกราคม 2014) คือ:
drop schema public cascade;
create schema public;
วิธีนี้ใช้ได้ผลอย่างไรก็ตามถ้าคุณตั้งใจจะเรียกคืนสคีมาสาธารณะกลับสู่สถานะที่บริสุทธิ์นี่จะไม่ทำงานอย่างเต็มที่ ภายใต้ pgAdmin III สำหรับ PostgreSQL 9.3.1 หากคุณคลิกที่สคีมา "สาธารณะ" ที่สร้างขึ้นด้วยวิธีนี้และดูใน "บานหน้าต่าง SQL" คุณจะเห็นสิ่งต่อไปนี้:
-- Schema: public
-- DROP SCHEMA public;
CREATE SCHEMA public
AUTHORIZATION postgres;
อย่างไรก็ตามในทางตรงกันข้ามฐานข้อมูลใหม่จะมีดังต่อไปนี้:
-- Schema: public
-- DROP SCHEMA public;
CREATE SCHEMA public
AUTHORIZATION postgres;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
COMMENT ON SCHEMA public
IS 'standard public schema';
สำหรับฉันใช้ python web framework ที่สร้างตารางฐานข้อมูล (web2py) โดยใช้ปัญหาที่เกิดขึ้นในอดีต:
<class 'psycopg2.ProgrammingError'> no schema has been selected to create in
ดังนั้นในใจของฉันคำตอบที่ถูกต้องคือ:
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
COMMENT ON SCHEMA public IS 'standard public schema';
นอกจากนี้โปรดทราบว่าให้ออกคำสั่งเหล่านี้ใน pgAdmin III ฉันใช้เครื่องมือ Query (ไอคอนรูปแว่นขยาย "เรียกใช้คำสั่ง SQL ที่ไม่เหมาะสม") หรือคุณสามารถใช้ปลั๊กอิน -> คอนโซล PSQL
บันทึก
หากคุณมีการติดตั้งส่วนขยายใด ๆ พวกเขาจะลดลงเมื่อคุณวางสคีมาดังนั้นคุณควรจดบันทึกสิ่งที่คุณต้องการติดตั้งแล้วดำเนินการคำสั่งตามความจำเป็น เช่น
CREATE EXTENSION postgis;
drop
จากนั้นcreate
) ใช้เพื่อทำงานกับ PostgreSQL 9.1 หลังจากอัพเกรดเป็น 9.3 grant
จำเป็นต้องเพิ่มทั้งสองอย่าง
คุณสามารถวางตารางทั้งหมดด้วย
DO $$ DECLARE
r RECORD;
BEGIN
-- if the schema you operate on is not "current", you will want to
-- replace current_schema() in query with 'schematodeletetablesfrom'
-- *and* update the generate 'DROP...' accordingly.
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
END LOOP;
END $$;
IMO นี้ดีกว่าdrop schema public
เพราะคุณไม่จำเป็นต้องสร้างใหม่schema
และเรียกคืนทุนทั้งหมด
โบนัสเพิ่มเติมที่ไม่จำเป็นต้องใช้ภาษาสคริปต์ภายนอกหรือการคัดลอก SQL ที่สร้างขึ้นกลับไปที่ล่าม
drop schema
เคล็ดลับได้เนื่องจากผู้ใช้ไม่ใช่เจ้าของสคีมาเท่านั้นของตาราง หนึ่งนี้ทำงานแม้ว่า :)
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
นี้ด้วย: EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
หากทุกสิ่งที่คุณต้องการที่จะวางเป็นเจ้าของโดยผู้ใช้เดียวกันคุณสามารถใช้:
drop owned by the_user;
สิ่งนี้จะลดทุกอย่างที่ผู้ใช้เป็นเจ้าของ
ซึ่งรวมถึงมุมมอง materialized, มุมมอง, ลำดับ, ทริกเกอร์, schemas, ฟังก์ชั่น, ประเภท, มวลรวม, โอเปอเรเตอร์, โดเมนและอื่น ๆ (ดังนั้นจริง ๆ : ทุกอย่าง ) ที่the_user
เป็นเจ้าของ (= สร้าง)
คุณต้องแทนที่the_user
ด้วยชื่อผู้ใช้จริงในขณะนี้ไม่มีตัวเลือกที่จะทิ้งทุกอย่างสำหรับ "ผู้ใช้ปัจจุบัน" ที่จะเกิดขึ้น 9.5 drop owned by current_user
รุ่นจะมีตัวเลือก
รายละเอียดเพิ่มเติมในคู่มือ: http://www.postgresql.org/docs/current/static/sql-drop-owned.html
public
สคีมาของฉันเป็นของpostgres
แต่ทุกอย่างอื่นเป็นของผู้ใช้ที่เฉพาะเจาะจงดังนั้นการวางทุกสิ่งที่เป็นของผู้ใช้นั้นจะล้างฐานข้อมูลยกเว้นสคีมา
ตาม Pablo ด้านบนเพียงแค่วางจาก schema ที่เฉพาะเจาะจงด้วยความเคารพกรณี:
select 'drop table "' || tablename || '" cascade;'
from pg_tables where schemaname = 'public';
where schemaname='public'
ส่วนนั้นสำคัญหรือไม่
drop schema public cascade;
ควรทำเคล็ดลับ
CREATE SCHEMA public;
คุณยังจะต้องสร้างขึ้นอีกครั้งหลังจากนั้นก็จะเพิ่มตารางกลับมาพร้อมกับ ดูstackoverflow.com/a/14286370สำหรับข้อมูลเพิ่มเติม
ติดตาม Pablo และ LenW ต่อไปนี้เป็นหนึ่งในสายการบินที่ทำทุกอย่างทั้งเตรียมและดำเนินการ:
psql -U $PGUSER $PGDB -t -c "select 'drop table \"' || tablename || '\" cascade;' from pg_tables where schemaname = 'public'" | psql -U $PGUSER $PGDB
NB: ตั้งหรือแทนที่$PGUSER
และ$PGDB
ด้วยค่าที่คุณต้องการ
หากคุณมีภาษาขั้นตอนการติดตั้ง PL / PGSQL คุณสามารถใช้สิ่งต่อไปนี้เพื่อลบทุกอย่างโดยไม่ต้องใช้สคริปต์ภายนอกของเชลล์ / Perl
DROP FUNCTION IF EXISTS remove_all();
CREATE FUNCTION remove_all() RETURNS void AS $$
DECLARE
rec RECORD;
cmd text;
BEGIN
cmd := '';
FOR rec IN SELECT
'DROP SEQUENCE ' || quote_ident(n.nspname) || '.'
|| quote_ident(c.relname) || ' CASCADE;' AS name
FROM
pg_catalog.pg_class AS c
LEFT JOIN
pg_catalog.pg_namespace AS n
ON
n.oid = c.relnamespace
WHERE
relkind = 'S' AND
n.nspname NOT IN ('pg_catalog', 'pg_toast') AND
pg_catalog.pg_table_is_visible(c.oid)
LOOP
cmd := cmd || rec.name;
END LOOP;
FOR rec IN SELECT
'DROP TABLE ' || quote_ident(n.nspname) || '.'
|| quote_ident(c.relname) || ' CASCADE;' AS name
FROM
pg_catalog.pg_class AS c
LEFT JOIN
pg_catalog.pg_namespace AS n
ON
n.oid = c.relnamespace WHERE relkind = 'r' AND
n.nspname NOT IN ('pg_catalog', 'pg_toast') AND
pg_catalog.pg_table_is_visible(c.oid)
LOOP
cmd := cmd || rec.name;
END LOOP;
FOR rec IN SELECT
'DROP FUNCTION ' || quote_ident(ns.nspname) || '.'
|| quote_ident(proname) || '(' || oidvectortypes(proargtypes)
|| ');' AS name
FROM
pg_proc
INNER JOIN
pg_namespace ns
ON
(pg_proc.pronamespace = ns.oid)
WHERE
ns.nspname =
'public'
ORDER BY
proname
LOOP
cmd := cmd || rec.name;
END LOOP;
EXECUTE cmd;
RETURN;
END;
$$ LANGUAGE plpgsql;
SELECT remove_all();
แทนที่จะพิมพ์สิ่งนี้ในพรอมต์ "psql" ฉันขอแนะนำให้คุณคัดลอกไปยังไฟล์แล้วส่งไฟล์เป็นอินพุตไปยัง psql โดยใช้ตัวเลือก "--file" หรือ "-f":
psql -f clean_all_pg.sql
เครดิตที่เครดิตครบกำหนด: ฉันเขียนฟังก์ชัน แต่คิดว่าข้อความค้นหา (หรืออย่างน้อยคำถามแรก) มาจากใครบางคนในรายการส่งเมล pgsql เมื่อหลายปีก่อน จำไม่ได้ว่าเมื่อไหร่หรืออย่างใดอย่างหนึ่ง
หากคุณต้องการทำนุกทุกโต๊ะคุณสามารถแจกจ่ายนิโคตินเช่นแบบเรียงซ้อนโดยการวางตารางทั้งหมดลงในคำสั่งเดียว สิ่งนี้ทำให้การดำเนินการเร็วขึ้น
SELECT 'TRUNCATE TABLE ' || string_agg('"' || tablename || '"', ', ') || ';'
FROM pg_tables WHERE schemaname = 'public';
ดำเนินการโดยตรง:
DO $$
DECLARE tablenames text;
BEGIN
tablenames := string_agg('"' || tablename || '"', ', ')
FROM pg_tables WHERE schemaname = 'public';
EXECUTE 'TRUNCATE TABLE ' || tablenames;
END; $$
แทนที่TRUNCATE
ด้วยDROP
ตามความเหมาะสม
public
schema อย่าลืมใส่ชื่อ schema ในนิพจน์string_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')
แทนการส่งชื่อตารางเท่านั้น
ฉันแก้ไขคำตอบของ Pablo เล็กน้อยเพื่อความสะดวกในการให้คำสั่ง SQL ที่สร้างขึ้นคืนเป็นสตริงเดียว:
select string_agg('drop table "' || tablename || '" cascade', '; ')
from pg_tables where schemaname = 'public'
ใช้สคริปต์นี้ใน pgAdmin:
DO $$
DECLARE
brow record;
BEGIN
FOR brow IN (select 'drop table "' || tablename || '" cascade;' as table_name from pg_tables where schemaname = 'public') LOOP
EXECUTE brow.table_name;
END LOOP;
END; $$
ในกรณี ... สคริปต์ Python แบบง่ายที่ล้างฐานข้อมูล Postgresql
import psycopg2
import sys
# Drop all tables from a given database
try:
conn = psycopg2.connect("dbname='akcja_miasto' user='postgres' password='postgres'")
conn.set_isolation_level(0)
except:
print "Unable to connect to the database."
cur = conn.cursor()
try:
cur.execute("SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_schema,table_name")
rows = cur.fetchall()
for row in rows:
print "dropping table: ", row[1]
cur.execute("drop table " + row[1] + " cascade")
cur.close()
conn.close()
except:
print "Error: ", sys.exc_info()[1]
ตรวจสอบให้แน่ใจว่าหลังจากการคัดลอกการเยื้องนั้นถูกต้องเนื่องจาก Python อาศัยอยู่
คุณสามารถใช้ฟังก์ชัน string_agg เพื่อสร้างรายการที่คั่นด้วยเครื่องหมายจุลภาคเหมาะสำหรับ DROP TABLE จากสคริปต์ทุบตี:
#!/bin/bash
TABLES=`psql $PGDB -t --command "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public'"`
echo Dropping tables:${TABLES}
psql $PGDB --command "DROP TABLE IF EXISTS ${TABLES} CASCADE"
หากคุณต้องการลบข้อมูล (ไม่ลบตาราง):
-- Truncate tables and restart sequnces
SELECT 'TRUNCATE TABLE "' || table_schema || '"."' || table_name || '" RESTART IDENTITY CASCADE;'
FROM information_schema.tables
WHERE table_catalog = '<database>' AND table_schema = '<schema>';
หรือถ้าคุณต้องการตารางหล่นคุณสามารถใช้ sql นี้:
-- For tables
SELECT 'DROP TABLE "' || table_schema || '"."' || table_name || '" CASCADE;'
FROM information_schema.tables
WHERE table_catalog = '<database>' AND table_schema = '<schema>';
-- For sequences
SELECT 'DROP SEQUENCE d_a_seq "' || sequence_schema || '"."' || sequence_name || '";'
FROM information_schema.sequences
WHERE sequence_catalog = '<database>' AND sequence_schema = '<schema>';
หมายเหตุ: คำตอบของฉันเกี่ยวกับการลบตารางและวัตถุฐานข้อมูลอื่น ๆ สำหรับการลบข้อมูลทั้งหมดในตารางเช่นการตัดตารางทั้งหมด Endre ทั้งสองได้จัดทำคำสั่งที่ดำเนินการอย่างดี (การดำเนินการโดยตรง) ในทำนองเดียวกันในเดือนต่อมา
สำหรับกรณีที่คุณไม่สามารถเพียงแค่DROP SCHEMA public CASCADE;
, DROP OWNED BY current_user;
หรือบางสิ่งบางอย่างที่นี่เป็นสคริปต์ SQL แบบสแตนด์อะโลนที่ผมเขียนซึ่งเป็นธุรกรรมที่ปลอดภัย (เช่นคุณสามารถวางไว้ระหว่างBEGIN;
และทั้งROLLBACK;
ที่จะเพียงแค่การทดสอบออกหรือCOMMIT;
ทำจริงโฉนด) และ ล้างค่าวัตถุฐานข้อมูล“ ทั้งหมด” …ทั้งหมดที่ใช้ในฐานข้อมูลที่แอปพลิเคชันของเราใช้หรือฉันอาจเพิ่มอย่างสมเหตุสมผลซึ่งก็คือ:
CHECK
,, UNIQUE
)VIEW
s (ปกติหรือปรากฏขึ้น)public
schemata nōn-default (เช่นไม่ใช่หรือ DB-internal) schemata“ เรา” เป็นของตัวเอง: สคริปต์นี้มีประโยชน์เมื่อรันเป็น“ ไม่ใช่ superuser ฐานข้อมูล”; superuser สามารถปล่อยschemata ทั้งหมด (อันที่สำคัญจริงๆยังคงยกเว้นอย่างชัดเจน)ไม่ลดลงเป็น (บางเจตนาบางเพียงเพราะฉันไม่มีตัวอย่างในฐานข้อมูลของเรา):
public
สคี (เช่นสำหรับสิ่งที่ส่วนขยายที่ให้ไว้ในพวกเขา)นี่คือจริงๆมีประโยชน์สำหรับกรณีที่การถ่ายโอนข้อมูลที่คุณต้องการที่จะเรียกคืนเป็นรุ่นคีมาฐานข้อมูลที่แตกต่างกัน (เช่นกับ Debian dbconfig-common
, เสียหายหรือ Liquibase / DB-Manul) มากกว่าฐานข้อมูลที่คุณต้องการเรียกคืนมันเข้าไป
ฉันยังมีรุ่นที่ลบ“ ทุกอย่างยกเว้นสองตารางและสิ่งที่เป็นของพวกเขา” (ลำดับการทดสอบด้วยตนเองขอโทษฉันรู้น่าเบื่อ) ในกรณีที่ใครบางคนสนใจ ความต่างมีขนาดเล็ก ติดต่อฉันหรือตรวจสอบ repo นี้ถ้าสนใจ
-- Copyright © 2019, 2020
-- mirabilos <t.glaser@tarent.de>
--
-- 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; $$;
ทดสอบยกเว้นการเพิ่มในภายหลัง ( extensions
สนับสนุนโดยClémentPrévost ) บน PostgreSQL 9.6 ( jessie-backports
) การทดสอบการกำจัดแบบรวมในวันที่ 9.6 และ 12.2 การทดสอบขั้นตอนการทดสอบในวันที่ 12.2 เช่นกัน ยินดีต้อนรับการแก้ไขข้อผิดพลาดและการปรับปรุงเพิ่มเติม!
DROP FUNCTION
ล้มเหลวสำหรับโพรซีเดอร์และในทางกลับกัน ฉันแก้ไขส่วนของฟังก์ชั่นเป็น: AND pp.prokind ='f' -- Function
หรือAND pp.prokind ='p' -- Procedure
proisagg
) ใน≤ 10.x และมวลรวมและขั้นตอน ( prokind
) ใน≥ 11 (ตรวจสอบแบบไดนามิก) และทดสอบทั้งสองขอบคุณสำหรับคำใบ้
นี่เป็นคำถามที่น่าสนใจมากและคุณจะทำมันได้หลายวิธี ฉันหวังว่านี่จะเป็นประโยชน์กับคุณ
- โดยวางและสร้างสคีมาปัจจุบันใหม่
โดยทั่วไปเรามีpublic
สคีมาเป็นค่าเริ่มต้น ดังนั้นฉันใช้มันเป็นตัวอย่าง
DROP SCHEMA `public` CASCADE;
CREATE SCHEMA `public`;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
หากคุณใช้ PostgreSQL 9.3 หรือสูงกว่าคุณอาจต้องกู้คืนค่าเริ่มต้น
ข้อดี:
การทำเช่นนี้จะเป็นการล้างโครงสร้างทั้งหมดและสร้างใหม่เป็นแบบใหม่
จุดด้อย:
คุณจะสูญเสียหน่วยงานอื่น ๆ เกินไปเช่นFunctions
, Views
, Materialized views
ฯลฯ
- โดยใช้การดึงชื่อตารางทั้งหมดจาก
pg_tables
ตาราง
ร้านค้า PostgreSQL pg_table
ทุกตารางบนโต๊ะบันทึกชื่อ
SELECT
'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;'
from
pg_tables WHERE schemaname = 'public';
อย่างที่คุณเห็นโดยการใช้เคียวรี่ย่อยเราสามารถลบตารางทั้งหมดออกจากสคีมาได้
ข้อดี:
เมื่อเอนทิตีข้อมูลอื่นมีความสำคัญและคุณเพียงต้องการลบเฉพาะตารางจากสคีมาวิธีการนี้จะเป็นประโยชน์กับคุณจริงๆ
คุณต้องวางตารางและลำดับนี่คือสิ่งที่ทำงานให้ฉัน
psql -qAtX -c "select 'DROP TABLE IF EXISTS ' || quote_ident(table_schema) || '.' || quote_ident(table_name) || ' CASCADE;' FROM information_schema.tables where table_type = 'BASE TABLE' and not table_schema ~ '^(information_schema|pg_.*)$'" | psql -qAtX
psql -qAtX -c "select 'DROP SEQUENCE IF EXISTS ' || quote_ident(relname) || ' CASCADE;' from pg_statio_user_sequences;" | psql -qAtX
ก่อนที่คุณจะเรียกใช้คำสั่งที่คุณอาจต้อง sudo su / กับpostgres
ผู้ใช้หรือ (การเชื่อมต่อการส่งออกรายละเอียดPGHOST
, PGPORT
, PGUSER
และPGPASSWORD
) แล้วexport PGDATABASE=yourdatabase
Rake task สำหรับ Rails เพื่อทำลายตารางทั้งหมดในฐานข้อมูลปัจจุบัน
namespace :db do
# rake db:drop_all_tables
task drop_all_tables: :environment do
query = <<-QUERY
SELECT
table_name
FROM
information_schema.tables
WHERE
table_type = 'BASE TABLE'
AND
table_schema NOT IN ('pg_catalog', 'information_schema');
QUERY
connection = ActiveRecord::Base.connection
results = connection.execute query
tables = results.map do |line|
table_name = line['table_name']
end.join ", "
connection.execute "DROP TABLE IF EXISTS #{ tables } CASCADE;"
end
end
rake db:create
นั้นฉันก็วิ่ง คุณสามารถทำเคล็ดลับสตีฟและลบรหัสtable_name =
และการเปลี่ยนแปลง", "
สำหรับ","
และ#{ tables }
สำหรับ#{tables}
ขั้นตอนต่อไปนี้อาจเป็นประโยชน์ (สำหรับผู้ใช้ linux):
ในตอนแรกให้ป้อนpostgres
คำสั่งโดยทำตามคำสั่งต่อไปนี้:
sudo -u postgres psql
ป้อนฐานข้อมูลด้วยคำสั่งนี้ (ชื่อฐานข้อมูลของฉันคือmaoss
:):
\c maoss
ตอนนี้ป้อนคำสั่งสำหรับการดร็อปตารางทั้งหมด:
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
ฉันปรับปรุงวิธีทุบตีจาก jamie โดยการดูแลมุมมองเพราะเขาเพียงเคารพประเภทตาราง "ตารางฐาน" ซึ่งเป็นค่าเริ่มต้น
รหัสทุบตีต่อไปนี้จะเป็นการลบมุมมองก่อนจากนั้นส่วนที่เหลือทั้งหมด
#!/usr/bin/env bash
PGDB="yourDB"
# By exporting user & pass your dont need to interactively type them on execution
export PGUSER="PGusername"
export PGPASSWORD="PGpassword"
VIEWS=`psql -d $PGDB -t --command "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public' AND table_type='VIEW'"`
BASETBLS=`psql -d $PGDB -t --command "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE'"`
echo Dropping views:${VIEWS}
psql $PGDB --command "DROP VIEW IF EXISTS ${VIEWS} CASCADE"
echo Dropping tables:${BASETBLS}
psql $PGDB --command "DROP TABLE IF EXISTS ${BASETBLS} CASCADE"
psql -d $PGDB -t --command "SELECT string_agg(sequence_name, ',') FROM information_schema.sequences WHERE sequence_schema='public' AND sequence_catalog='$PGDB'"
ในไฟล์แบตช์ Windows:
@echo off
FOR /f "tokens=2 delims=|" %%G IN ('psql --host localhost --username postgres --command="\dt" YOUR_TABLE_NAME') DO (
psql --host localhost --username postgres --command="DROP table if exists %%G cascade" sfkb
echo table %%G dropped
)
ดีเนื่องจากฉันชอบทำงานจากบรรทัดคำสั่ง ...
psql -U <user> -d <mydb> -c '\dt' | cut -d ' ' -f 4 | sed -e "s/^/drop table if exists /" | sed -e "s/$/;/"
-c '\dt'
จะเรียกใช้คำสั่ง list tables
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | _d_psidxddlparm | table | djuser
public | _d_psindexdefn | table | djuser
cut -d ' ' -f 4
ตอนนี้ไพพ์เอาต์พุตเพื่อคว้าฟิลด์ที่ 4 (เมื่อใช้พื้นที่เป็นตัวคั่น) ซึ่งเป็นตาราง
sed
จะถูกใช้เพื่อนำหน้า a drop table
และต่อท้าย;
ตัวคั่นคำสั่ง
| egrep '_d_'
- วางลงในgrep
บางส่วนและคุณสามารถเลือกได้มากขึ้นเกี่ยวกับตารางที่คุณวาง
drop table if exists _d_psidxddlparm;
drop table if exists _d_psindexdefn;
หมายเหตุ: ตามที่เขียนไว้สิ่งนี้จะสร้างแถวปลอมสำหรับ\dt
เอาต์พุตคำสั่งของส่วนหัวคอลัมน์และแถวทั้งหมดในตอนท้าย ผมหลีกเลี่ยงการว่าโดย grepping แต่คุณสามารถใช้และhead
tail
วิธีที่ง่ายที่สุดคือการวางสคีมาสาธารณะตามที่คนอื่น ๆ แนะนำไว้ในคำตอบก่อนหน้า อย่างไรก็ตามนี่ไม่ใช่วิธีที่ดี คุณไม่มีทางรู้ว่าสิ่งที่ทำกับสคีมาสาธารณะที่ถูกลืมไปแล้วและไม่มีการจัดทำเป็นเอกสาร คุณไม่รู้ด้วยซ้ำว่าสิ่งนี้จะได้ผลเหมือนกันในอนาคตหรือไม่ ใน V9 มันน่าจะดี แต่ใน V10 ผู้ใช้ของคุณทุกคนจะเข้าถึงสคีมาได้ไม่เต็มที่และจะต้องได้รับสิทธิ์การเข้าถึงอีกครั้งมิฉะนั้นแอปพลิเคชันของคุณจะแตก ฉันยังไม่ได้ตรวจสอบ V11 แต่ประเด็นก็คือคุณไม่เคยรู้ว่าอะไรจะแตกเมื่อคุณย้ายจากเครื่องหนึ่งไปอีกเครื่องหนึ่งไปยังอีกที่หนึ่งหรือหลายรุ่น นอกจากนี้ยังไม่สามารถทำได้หากคุณเป็นผู้ใช้ที่สามารถเข้าถึงฐานข้อมูล แต่ไม่ใช่สคีมา
หากคุณต้องการทำสิ่งนี้โดยทางโปรแกรมแล้วคำตอบอื่น ๆ ข้างต้นครอบคลุมสิ่งนี้ แต่สิ่งหนึ่งที่คำตอบข้างต้นไม่ได้พิจารณาคือให้ Postgres ทำงานให้คุณ หากคุณใช้ pg_dump พร้อมกับตัวเลือก -c ดังนี้:
sudo su postgres -c "pg_dump -U postgres WhateverDB -c -f "/home/Anyone/DBBackupWhateverDB-ServerUnscheduled.sql""
ที่จะสร้างสคริปต์เรียกคืนฐานข้อมูลด้วยคำสั่ง sql ที่จะลบตารางทั้งหมด
หากจุดประสงค์เดียวในการถามคำถามคือการลบตารางก่อนที่จะกู้คืนการกู้คืนของคุณจะทำงานให้คุณ
อย่างไรก็ตามหากคุณต้องการสิ่งอื่นคุณสามารถคัดลอกคำสั่ง drop จากสคริปต์ sql