删除PostgreSQL中的所有表?

如何从命令行删除PostgreSQL中的所有表?

我不想丢弃数据库本身,只是所有的表和所有的数据。

如果你所有的表都在一个模式中,这种方法可以工作(下面的代码假定你的模式的名字是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; 

你可以编写一个查询来生成一个如下所示的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也将起作用。

撰写本文(2014年1月)时最为接受的答案是:

 drop schema public cascade; create schema public; 

这是行得通的,但是如果你的意图是把公共架构恢复到处女状态,这并不能完全完成任务。 在PostgreSQL 9.3.1的pgAdmin III下,如果你点击这样创build的“公共”模式并查看“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'; 

对于我使用创build数据库表(web2py)的python web框架,使用前者导致的问题:

 <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发出这些命令,我​​去了Plugins-> PSQL Console)

根据上面的Pablo,就具体模式而言,就个案而言:

 select 'drop table "' || tablename || '" cascade;' from pg_tables where schemaname = 'public'; 

您可以删除所有表格

 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 $$; 

海事组织这比drop schema public更好,因为你不需要重新创buildschema和恢复所有的授予。

额外的好处是,这不需要外部脚本语言,也不需要将生成的SQL复制粘贴回解释器。

如果您要删除的所有内容都由同一用户拥有 ,则可以使用:

 drop owned by the_user; 

您必须用实际的用户名replacethe_user ,目前没有选项可以删除“当前用户”的所有内容。 即将到来的9.5版本将drop owned by current_user拥有的选项drop owned by current_user

这也将删除the_user拥有(=创build)的视图,序列,触发器等。

手册中的更多细节: http : //www.postgresql.org/docs/current/static/sql-drop-owned.html

 drop schema public cascade; 

应该做的伎俩。

按照Pablo和LenW的说法,这里是一个单线程,完成所有的准备和执行:

psql -U $PGUSER $PGDB -t -c "select 'drop table \"' || tablename || '\" cascade;' from pg_tables where schemaname = 'public'" | psql -U $PGUSER $PGDB

注意:设置或者用你想要的值replace$PGUSER$PGDB

如果您安装了PL / PGSQL过程语言,则可以使用以下命令删除所有内容,而不使用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(); 

而不是在“psql”提示符下input,我build议你将它复制到一个文件中,然后使用“–file”或“-f”选项将该文件作为input传递给psql:

 psql -f clean_all_pg.sql 

信用到期的信用:我写了这个函数,但是认为这些查询(或者至less第一个)是多年前在某个pgsql邮件列表中的某个人的。 不记得确切的时间或哪一个。

以防万一…简单的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函数来创build一个逗号分隔的列表,对于DROP TABLE来说是完美的。 从一个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" 

Rails Rake任务用于销毁当前数据库中的所有表

 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 

你需要删除表和序列,这是为我工作

 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用户或(导出连接细节PGHOSTPGPORTPGUSERPGPASSWORD ),然后export PGDATABASE=yourdatabase

为了方便将生成的SQL命令作为一个string返回,我稍微修改了Pablo的答案:

 select string_agg('drop table "' || tablename || '" cascade', '; ') from pg_tables where schemaname = 'public' 

我通过照顾视图增强了jamie的bash方法,因为他只尊重默认的表types“base table”。

下面的bash代码先删除视图,然后删除所有其余的视图

 #!/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" 

在Windowsbatch file中:

 @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 )