删除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
用户或(导出连接细节PGHOST
, PGPORT
, PGUSER
和PGPASSWORD
),然后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 )