Làm cách nào tôi có thể thả tất cả các bảng trong PostgreSQL, hoạt động từ dòng lệnh?
Tôi không muốn bỏ cơ sở dữ liệu, chỉ tất cả các bảng và tất cả dữ liệu trong đó.
public
, bạn sẽ mất mọi tiện ích mở rộng đã cài đặt.
Làm cách nào tôi có thể thả tất cả các bảng trong PostgreSQL, hoạt động từ dòng lệnh?
Tôi không muốn bỏ cơ sở dữ liệu, chỉ tất cả các bảng và tất cả dữ liệu trong đó.
public
, bạn sẽ mất mọi tiện ích mở rộng đã cài đặt.
Câu trả lời:
Nếu tất cả các bảng của bạn nằm trong một lược đồ duy nhất, cách tiếp cận này có thể hoạt động (mã bên dưới giả định rằng tên của lược đồ của bạn là public
)
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
Nếu bạn đang sử dụng PostgreSQL 9.3 trở lên, bạn cũng có thể cần khôi phục các khoản trợ cấp mặc định.
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
pg_
) vì chúng nằm trong một lược đồ khác , pg_catalog
.
GRANT ALL ON SCHEMA public TO public;
sau khi tạo.
GRANT ALL
sau khi tạo?
Bạn có thể viết một truy vấn để tạo tập lệnh SQL như thế này:
select 'drop table "' || tablename || '" cascade;' from pg_tables;
Hoặc là:
select 'drop table if exists "' || tablename || '" cascade;' from pg_tables;
Trong trường hợp một số bảng được tự động loại bỏ do tùy chọn xếp tầng trong câu trước.
Ngoài ra, như đã nêu trong các nhận xét, bạn có thể muốn lọc các bảng bạn muốn thả theo tên lược đồ:
select 'drop table if exists "' || tablename || '" cascade;'
from pg_tables
where schemaname = 'public'; -- or any other schema
Và sau đó chạy nó.
Vinh quang COPY + PASTE cũng sẽ hoạt động.
drop schema public cascade;
, nhưng hầu như bạn luôn có quyền bỏ bảng.
Câu trả lời được chấp nhận nhiều nhất trong bài viết này (tháng 1 năm 2014) là:
drop schema public cascade;
create schema public;
Điều này không hoạt động, tuy nhiên nếu ý định của bạn là khôi phục lược đồ công cộng về trạng thái nguyên vẹn thì điều này không hoàn thành nhiệm vụ. Trong pgAdmin III cho PostgreQuery 9.3.1, nếu bạn nhấp vào lược đồ "công khai" được tạo theo cách này và tìm trong "ngăn SQL", bạn sẽ thấy như sau:
-- Schema: public
-- DROP SCHEMA public;
CREATE SCHEMA public
AUTHORIZATION postgres;
Tuy nhiên, ngược lại, một cơ sở dữ liệu hoàn toàn mới sẽ có những điều sau đây:
-- 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';
Đối với tôi sử dụng khung web python tạo các bảng cơ sở dữ liệu (web2py), sử dụng các sự cố đã gây ra trước đây:
<class 'psycopg2.ProgrammingError'> no schema has been selected to create in
Vì vậy, theo tôi, câu trả lời hoàn toàn chính xác là:
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';
Cũng lưu ý khi phát hành các lệnh này trong pgAdmin III, tôi đã sử dụng công cụ Truy vấn (biểu tượng kính lúp "Thực thi các truy vấn SQL khó hiểu") hoặc bạn có thể sử dụng Plugins-> Bảng điều khiển PSQL
Ghi chú
Nếu bạn có bất kỳ tiện ích mở rộng nào được cài đặt, chúng sẽ bị loại bỏ khi bạn thả lược đồ, vì vậy bạn nên lưu ý những gì bạn cần cài đặt và sau đó thực hiện các câu lệnh khi cần thiết. Ví dụ
CREATE EXTENSION postgis;
drop
sau đó create
) được sử dụng để hoạt động trên PostgreSQL 9.1. Sau khi nâng cấp lên 9.3, hai phụ grant
là cần thiết.
Bạn có thể thả tất cả các bảng với
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 điều này tốt hơn drop schema public
, bởi vì bạn không cần phải tạo lại schema
và khôi phục tất cả các khoản tài trợ.
Phần thưởng bổ sung mà điều này không yêu cầu ngôn ngữ kịch bản bên ngoài, cũng như sao chép SQL đã tạo trở lại trình thông dịch.
drop schema
thủ thuật vì người dùng không phải là chủ sở hữu của lược đồ, chỉ các bảng. Cái này hoạt động được :)
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
bằng cách này: EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
Nếu mọi thứ bạn muốn thả đều thuộc sở hữu của cùng một người dùng, thì bạn có thể sử dụng:
drop owned by the_user;
Điều này sẽ bỏ mọi thứ mà người dùng sở hữu.
Điều đó bao gồm các khung nhìn cụ thể, các khung nhìn, các chuỗi, trình kích hoạt, lược đồ, hàm, loại, tổng hợp, toán tử, miền, v.v (vì vậy, thực sự: mọi thứ ) the_user
sở hữu (= được tạo).
Bạn phải thay thế the_user
bằng tên người dùng thực tế, hiện tại không có tùy chọn để bỏ mọi thứ cho "người dùng hiện tại". Phiên bản 9.5 sắp tới sẽ có tùy chọn drop owned by current_user
.
Thêm chi tiết trong hướng dẫn sử dụng: http://www.postgresql.org/docs/civerse/static/sql-drop-own.html
public
lược đồ của tôi được sở hữu bởi postgres
, nhưng mọi thứ khác đều thuộc sở hữu của một người dùng cụ thể, do đó, bỏ mọi thứ thuộc sở hữu của người dùng đó sẽ xóa cơ sở dữ liệu ngoại trừ lược đồ.
Theo Pablo ở trên, chỉ cần thả từ một lược đồ cụ thể, liên quan đến trường hợp:
select 'drop table "' || tablename || '" cascade;'
from pg_tables where schemaname = 'public';
where schemaname='public'
một phần là đáng kể?
drop schema public cascade;
nên làm thủ thuật.
CREATE SCHEMA public;
. Đồng thời xem stackoverflow.com/a/14286370 để biết thêm thông tin
Theo Pablo và LenW, đây là một lớp lót thực hiện tất cả cả việc chuẩn bị và sau đó thực hiện:
psql -U $PGUSER $PGDB -t -c "select 'drop table \"' || tablename || '\" cascade;' from pg_tables where schemaname = 'public'" | psql -U $PGUSER $PGDB
NB: hoặc đặt hoặc thay thế $PGUSER
và $PGDB
với các giá trị bạn muốn
Nếu bạn đã cài đặt ngôn ngữ thủ tục PL / PGSQL, bạn có thể sử dụng cách sau để xóa mọi thứ mà không cần tập lệnh bên ngoài shell / 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();
Thay vì nhập cái này vào dấu nhắc "psql", tôi sẽ đề nghị bạn sao chép nó vào một tệp và sau đó chuyển tệp dưới dạng đầu vào sang psql bằng cách sử dụng các tùy chọn "--file" hoặc "-f":
psql -f clean_all_pg.sql
Tín dụng khi tín dụng đáo hạn: Tôi đã viết hàm, nhưng nghĩ rằng các truy vấn (hoặc ít nhất là đầu tiên) đến từ một người nào đó trong một trong các danh sách gửi thư của pssql cách đây nhiều năm. Đừng nhớ chính xác khi nào hoặc cái nào.
Nếu bạn muốn nuke tất cả các bảng bằng mọi cách, bạn có thể phân phối với các niceties như CASCADE bằng cách đặt tất cả các bảng vào một câu lệnh. Điều này cũng làm cho việc thực hiện nhanh hơn.
SELECT 'TRUNCATE TABLE ' || string_agg('"' || tablename || '"', ', ') || ';'
FROM pg_tables WHERE schemaname = 'public';
Thực hiện nó trực tiếp:
DO $$
DECLARE tablenames text;
BEGIN
tablenames := string_agg('"' || tablename || '"', ', ')
FROM pg_tables WHERE schemaname = 'public';
EXECUTE 'TRUNCATE TABLE ' || tablenames;
END; $$
Thay thế TRUNCATE
bằng DROP
như áp dụng.
public
lược đồ, đừng quên đưa tên lược đồ vào biểu thức: string_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')
thay vì chỉ truyền tên bảng.
Sử dụng tập lệnh này trong 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; $$
Chỉ trong trường hợp ... Tập lệnh Python đơn giản giúp dọn dẹp cơ sở dữ liệu 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]
Hãy chắc chắn rằng sau khi sao chép nó, thụt lề là đúng vì Python dựa vào nó.
Bạn có thể sử dụng hàm string_agg để tạo danh sách được phân tách bằng dấu phẩy, hoàn hảo cho DROP TABLE. Từ một tập lệnh bash:
#!/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"
Nếu bạn muốn xóa dữ liệu (không xóa bảng):
-- 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>';
Hoặc nếu bạn muốn thả bảng, bạn có thể sử dụng sql này:
-- 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>';
Lưu ý: câu trả lời của tôi là về việc thực sự xóa các bảng và các đối tượng cơ sở dữ liệu khác; để xóa tất cả dữ liệu trong các bảng, tức là cắt bớt tất cả các bảng , Endre Cả hai đã cung cấp một câu lệnh (thực thi trực tiếp) được thực hiện tốt tương tự một tháng sau đó.
Đối với các trường hợp bạn không thể DROP SCHEMA public CASCADE;
, DROP OWNED BY current_user;
hoặc một cái gì đó, đây là tập lệnh SQL độc lập mà tôi đã viết, nó an toàn cho giao dịch (nghĩa là bạn có thể đặt nó giữa BEGIN;
và ROLLBACK;
để kiểm tra hoặc COMMIT;
thực hiện hành động đó) và thực sự làm việc đó) và Dọn dẹp tất cả các đối tượng cơ sở dữ liệu của thành phố tốt, tất cả những thứ được sử dụng trong cơ sở dữ liệu mà ứng dụng của chúng tôi sử dụng hoặc tôi có thể thêm vào một cách hợp lý, đó là:
CHECK
,, UNIQUE
)VIEW
s (bình thường hoặc vật chất hóa)public
hoặc DB-Internal), chúng tôi sở hữu: kịch bản này rất hữu ích khi được chạy dưới dạng không phải là một siêu người dùng cơ sở dữ liệu. một siêu người dùng có thể loại bỏ tất cả các schemata (mặc dù những cái thực sự quan trọng vẫn bị loại trừ rõ ràng)Không bị rơi là (một số cố ý; một số chỉ vì tôi không có ví dụ trong DB của chúng tôi):
public
giản đồ (ví dụ như cho các công cụ mở rộng-cung cấp trong họ)Điều này thực sự hữu ích cho các trường hợp khi kết xuất mà bạn muốn khôi phục thuộc phiên bản lược đồ cơ sở dữ liệu khác (ví dụ với Debian dbconfig-common
, Flyway hoặc Liquibase / DB-Manul) so với cơ sở dữ liệu bạn muốn khôi phục.
Tôi cũng đã có một phiên bản xóa tất cả mọi thứ ngoại trừ hai bảng và những gì thuộc về họ (một chuỗi, được kiểm tra thủ công, xin lỗi, tôi biết, nhàm chán) trong trường hợp ai đó quan tâm; khác biệt là nhỏ. Liên hệ với tôi hoặc kiểm tra repo này nếu quan tâm.
-- 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; $$;
Đã thử nghiệm, ngoại trừ các bổ sung sau này (được extensions
đóng góp bởi Clément Prévost ), trên PostgreQuery 9.6 ( jessie-backports
). Loại bỏ tổng hợp được thử nghiệm vào ngày 9.6 và 12.2, loại bỏ quy trình cũng được thử nghiệm vào ngày 12.2. Sửa lỗi và cải tiến hơn nữa chào mừng!
DROP FUNCTION
không thành công cho một thủ tục và ngược lại. Tôi đã sửa đổi phần chức năng này: AND pp.prokind ='f' -- Function
hoặcAND pp.prokind ='p' -- Procedure
proisagg
) trên ≤ 10.x và các tổng hợp và quy trình ( prokind
) trên 11 (được kiểm tra động) và kiểm tra cả cảm ơn về gợi ý.
Đây là một câu hỏi thực sự thú vị và bạn sẽ giải quyết nó thông qua nhiều cách. Tôi hy vọng điều này sẽ hữu ích cho bạn.
- Bằng cách loại bỏ và tạo lại lược đồ hiện tại
Ở đây, nói chung, chúng tôi có một public
lược đồ theo mặc định. Vì vậy, tôi đang sử dụng nó như một ví dụ.
DROP SCHEMA `public` CASCADE;
CREATE SCHEMA `public`;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Nếu bạn đang sử dụng PostgreSQL 9.3 trở lên, bạn cũng có thể cần khôi phục các khoản trợ cấp mặc định.
Ưu điểm:
Điều này sẽ làm sạch toàn bộ Schema và tạo lại nó như một cái mới.
Nhược điểm:
Bạn sẽ mất các đơn vị khác quá như Functions
, Views
, Materialized views
vv
- Bằng cách sử dụng tìm nạp tất cả các tên
pg_tables
bảng từ bảng.
PostgreSQL lưu trữ tất cả các bảng trên bảng ghi của nó có tên pg_table
.
SELECT
'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;'
from
pg_tables WHERE schemaname = 'public';
Như bạn có thể thấy, bằng cách sử dụng truy vấn con, Chúng tôi có thể xóa toàn bộ bảng khỏi lược đồ.
Ưu điểm:
Khi các thực thể dữ liệu khác là Quan trọng và bạn chỉ muốn xóa các bảng khỏi lược đồ, phương pháp này sẽ thực sự hữu ích cho bạn.
Bạn cần bỏ các bảng và trình tự, đây là những gì làm việc cho tôi
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
trước khi bạn chạy các lệnh bạn có thể cần phải sudo / su cho người postgres
dùng hoặc (kết nối xuất khẩu chi tiết PGHOST
, PGPORT
, PGUSER
và PGPASSWORD
) và sau đóexport PGDATABASE=yourdatabase
Tác vụ cào cho Rails để hủy tất cả các bảng trong cơ sở dữ liệu hiện tại
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
, tôi chạy nó. Bạn có thể làm mũi Steve và loại bỏ mã table_name =
và thay đổi ", "
cho ","
và #{ tables }
fo#{tables}
Các bước sau có thể hữu ích (Đối với người dùng linux):
Đầu tiên, nhập postgres
dấu nhắc lệnh bằng lệnh sau:
sudo -u postgres psql
Nhập cơ sở dữ liệu bằng lệnh này (tên cơ sở dữ liệu của tôi là maoss
:):
\c maoss
Bây giờ hãy nhập lệnh để thả tất cả các bảng:
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Tôi đã cải tiến phương thức bash từ jamie bằng cách quan tâm đến các khung nhìn vì anh ta chỉ tôn trọng loại bảng "bảng cơ sở" là mặc định.
mã bash sau xóa các khung nhìn trước và sau đó tất cả các phần còn lại
#!/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'"
tốt, vì tôi thích làm việc từ dòng lệnh ...
psql -U <user> -d <mydb> -c '\dt' | cut -d ' ' -f 4 | sed -e "s/^/drop table if exists /" | sed -e "s/$/;/"
-c '\dt'
sẽ gọi lệnh bảng danh sách.
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | _d_psidxddlparm | table | djuser
public | _d_psindexdefn | table | djuser
cut -d ' ' -f 4
bây giờ, đặt đầu ra của nó để lấy trường thứ 4 (khi sử dụng khoảng trắng làm dấu phân cách), đó là bảng.
sed
sau đó được sử dụng để tiền tố a drop table
và hậu tố ;
phân tách lệnh.
| egrep '_d_'
- Đưa nó vào grep
một số chi tiết và bạn có thể chọn lọc hơn về những bảng bạn thả.
drop table if exists _d_psidxddlparm;
drop table if exists _d_psindexdefn;
Lưu ý: như đã viết, điều này sẽ tạo ra các hàng không có thật cho \dt
đầu ra lệnh của các tiêu đề cột và tổng số hàng ở cuối. Tôi tránh điều đó bằng cách grepping, nhưng bạn có thể sử dụng head
và tail
.
Cách dễ nhất là bỏ lược đồ công khai như những người khác đã đề xuất trong các câu trả lời trước. Tuy nhiên, đây KHÔNG phải là một cách tốt. Bạn không bao giờ biết những gì đã được thực hiện cho lược đồ công cộng đã bị lãng quên và không được ghi lại. Bạn cũng không biết nếu điều này sẽ làm việc tương tự trong tương lai. Trong V9, nó sẽ ổn, nhưng trong V10, tất cả người dùng của bạn sẽ mất quyền truy cập vào lược đồ và phải được cấp lại quyền truy cập nếu không ứng dụng của bạn sẽ bị hỏng. Tôi chưa kiểm tra V11, nhưng vấn đề là bạn không bao giờ biết cái gì sẽ hỏng khi bạn chuyển từ máy này sang máy khác, trang này sang trang khác hoặc phiên bản sang phiên bản. Nó cũng không thể được thực hiện nếu bạn là người dùng có quyền truy cập vào cơ sở dữ liệu, nhưng không truy cập vào lược đồ.
Nếu bạn cần thực hiện việc này theo chương trình thì các câu trả lời khác ở trên sẽ bao gồm điều này, nhưng một điều mà các câu trả lời ở trên không xem xét là để Postgres thực hiện công việc cho bạn. Nếu bạn sử dụng pg_dump với tùy chọn -c như dưới đây:
sudo su postgres -c "pg_dump -U postgres WhateverDB -c -f "/home/Anyone/DBBackupWhateverDB-ServerUnscheduled.sql""
Điều đó sẽ tạo ra một kịch bản khôi phục DB với các câu lệnh sql sẽ xóa tất cả các bảng.
Nếu mục đích duy nhất khi đặt câu hỏi là xóa các bảng trước khi khôi phục, thì khôi phục của bạn sẽ thực hiện công việc cho bạn.
Tuy nhiên, nếu bạn cần nó cho một cái gì đó khác, bạn chỉ cần sao chép các câu lệnh thả từ tập lệnh sql.