如何从命令行删除PostgreSQL中的所有表?
我不想删除数据库本身,只想删除其中的所有表和所有数据。
如何从命令行删除PostgreSQL中的所有表?
我不想删除数据库本身,只想删除其中的所有表和所有数据。
当前回答
如果安装了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();
我建议您将其复制到一个文件中,然后使用“--file”或“-f”选项将该文件作为输入传递给psql,而不是在“psql”提示符下键入:
psql -f clean_all_pg.sql
值得称赞的地方:我写了这个函数,但我认为这些查询(至少第一个)来自几年前pgsql邮件列表中的某个人。不记得确切的时间或哪一天。
其他回答
继Pablo和LenW之后,这里有一个单行程序,它既准备又执行:
psql-U$PGUSER$PGDB-t-c“从pg_tables中选择'drop table\”'||tablename||'\“cascade;',其中schemaname='public'”|psql-U$PGUSER$PGDB
注意:设置$PGUSER和$PGDB或将其替换为所需的值
你需要删除表和序列,这是对我有用的
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),然后导出PGDATABASE=yourdatabase
最简单的方法是删除公共模式,正如其他人在前面的答案中所建议的那样。然而,这不是一个好方法。你永远不知道对公共模式做了什么,因为它已经被遗忘,也没有被记录。你也不知道这是否会在未来发挥同样的作用。在V9中,这是很好的,但在V10中,所有用户都将失去对模式的访问,必须再次获得访问权限,否则应用程序将崩溃。我还没有检查过V11,但问题是,当你从一台机器移动到另一台机器、从一个站点移动到另个站点或从一个版本移动到另另一个版本时,你永远不知道会发生什么。如果您是有权访问数据库但不能访问模式的用户,则也无法执行此操作。
如果您需要以编程方式完成这项工作,那么上面的其他答案也涵盖了这一点,但上面的答案没有考虑到的一点是让Postgres为您完成这项任务。如果将pg_dump与-c选项一起使用,如下所示:
sudo su postgres -c "pg_dump -U postgres WhateverDB -c -f "/home/Anyone/DBBackupWhateverDB-ServerUnscheduled.sql""
这将创建一个包含sql语句的DB还原脚本,该脚本将删除所有表。
如果问这个问题的唯一目的是在还原之前删除表,那么还原将为您完成这项工作。
但是,如果您在其他方面需要它,您可以简单地从sql脚本复制drop语句。
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
下面是现成的查询:
选择
'drop table if exists "' || tablename || '" cascade;' as pg_drop
FROM
pg_tables
哪里
schemaname='your schema';