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

我不想删除数据库本身,只想删除其中的所有表和所有数据。


当前回答

这是一个非常有趣的问题,您可以通过多种方式完成:

1.通过删除并重新创建当前架构

这里,通常情况下,我们有一个默认的公共模式。所以,我用它作为一个例子。

-- Recreate the schema
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;

-- Restore default permissions
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

如果您使用PostgreSQL 9.3或更高版本,您可能还需要恢复默认授权。

赞成的意见:

这将清理整个架构并将其重新创建为新架构。

欺骗:

您将丢失其他实体,如函数、视图、物化视图等。

2.通过使用从pg_tables表中获取所有表名。

PostgreSQL将所有表存储在其名为pg_table的记录表中。

SELECT
  'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;' 
from
  pg_tables WHERE schemaname = 'public';

如您所见,通过使用子查询,我们可以从模式中删除整个表。

赞成的意见:

当其他数据实体很重要,并且您只想从模式中删除表时,这种方法对您非常有用。

3.终端

使用shell上的postgres用户登录

$ sudo -u postgres psql

连接数据库

$ \c mydatabase

粘贴这些命令:

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
     
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

注意:这一组命令与第一点类似,因此优点和缺点将保持不变。。

其他回答

如果安装了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邮件列表中的某个人。不记得确切的时间或哪一天。

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

这是一个非常有趣的问题,您可以通过多种方式完成:

1.通过删除并重新创建当前架构

这里,通常情况下,我们有一个默认的公共模式。所以,我用它作为一个例子。

-- Recreate the schema
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;

-- Restore default permissions
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

如果您使用PostgreSQL 9.3或更高版本,您可能还需要恢复默认授权。

赞成的意见:

这将清理整个架构并将其重新创建为新架构。

欺骗:

您将丢失其他实体,如函数、视图、物化视图等。

2.通过使用从pg_tables表中获取所有表名。

PostgreSQL将所有表存储在其名为pg_table的记录表中。

SELECT
  'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;' 
from
  pg_tables WHERE schemaname = 'public';

如您所见,通过使用子查询,我们可以从模式中删除整个表。

赞成的意见:

当其他数据实体很重要,并且您只想从模式中删除表时,这种方法对您非常有用。

3.终端

使用shell上的postgres用户登录

$ sudo -u postgres psql

连接数据库

$ \c mydatabase

粘贴这些命令:

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
     
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

注意:这一组命令与第一点类似,因此优点和缺点将保持不变。。

如果要删除数据(而不是删除表):

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

使用psql的基于终端的方法最适合我。我甚至创建了一个bash函数,因为它便于开发:

psqlDropTables() {
    PGPASSWORD=<your password>
    PGTABLE=<your table name>
    PGUSER=<your pg user name>
    PGPASSWORD=$PGPASSWORD psql -ah 127.0.0.1 $PGTABLE $PGUSER -c "
      SELECT
'DROP TABLE IF EXISTS \"' || tablename || '\" CASCADE;' from
pg_tables WHERE schemaname = 'public';" | grep DROP | awk 'NR>1{print $0}' | sed "s/\"/'/g" | PGPASSWORD=$PGPASSWORD xargs -i  psql -ah 127.0.0.1 $PGTABLE $PGUSER -c {}
}

它创建了此响应中所述的所有必需的放置表语句,将“替换为”并在DB上运行它们。