首页 文章

删除PostgreSQL中的所有表?

提问于
浏览
775

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

我想要删除数据库本身,只删除所有表及其中的所有数据 .

19 回答

  • 26

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

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

    或者如果你想要drop table你可以使用这个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>';
    
  • 6

    如果所有表都在单个模式中,则此方法可以工作(下面的代码假定模式的名称是 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;
    
  • 0

    截至撰写本文时(2014年1月),最受欢迎的答案是:

    drop schema public cascade;
    create schema public;
    

    这确实有效,但是如果您打算将公共模式恢复到其原始状态,那么这并不能完全完成任务 . 在PostgreSQL 9.3.1的pgAdmin III下,如果单击以这种方式创建的“公共”模式并查看“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';
    

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

    <class 'psycopg2.ProgrammingError'> no schema has been selected to create in
    

    So to my mind the fully correct answer is:

    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)

  • 2

    以防万一...简单的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依赖它 .

  • 18

    好吧,既然我喜欢在命令行工作......

    psql -U <user> -d <mydb> -c '\dt' | cut -d ' ' -f 4 | sed -e "s/^/drop table if exists /" | sed -e "s/$/;/"

    -c '\dt' 将调用list tables命令 .

    List of relations Schema | Name | Type | Owner --------+-------------------+-------+---------- public | _d_psidxddlparm | table | djuser public | _d_psindexdefn | table | djuser

    cut -d ' ' -f 4 现在,管道输出以获取第4个字段(当使用空格作为分隔符时),即表格 .

    然后使用 seddrop table 添加前缀,并为 ; 命令分隔符添加后缀 .

    | egrep '_d_' - 将它更多地导入 grep ,您可以更自由地选择丢弃的表格 .

    drop table if exists _d_psidxddlparm; drop table if exists _d_psindexdefn;

    注意:如上所述,这将为列 Headers 的 \dt 命令输出和末尾的总行生成伪造的行 . 我通过grepping来避免这种情况,但你可以使用 headtail .

  • 9

    您可以编写一个查询来生成这样的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也将起作用 .

  • 223

    在Pablo和LenW之后,这里有一个单行程,可以完成所有准备工作,然后执行:

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

    注意:使用您想要的值设置或替换 $PGUSER$PGDB

  • 38

    如果您要删除的所有内容都归同一个用户所有,那么您可以使用:

    drop owned by the_user;
    

    这将删除用户拥有的 everything .

    这包括 the_user 拥有(=创建)的物化视图,视图,序列,触发器,模式,函数,类型,聚合,运算符,域等(所以,真的: everything ) .

    您必须将 the_user 替换为实际的用户名,目前没有选项可以删除"the current user"的所有内容 . 即将推出的9.5版本将提供选项 drop owned by current_user .

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

  • 2
    drop schema public cascade;
    

    应该做的伎俩 .

  • 63

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

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

    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
    
  • 73

    您可以删除所有表格

    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这比 drop schema public 更好,因为您不需要重新创建 schema 并恢复所有授权 .

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

  • 7

    在Windows批处理文件中:

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

    如果您有PL / PGSQL过程语言installed,则可以使用以下内容删除所有内容而不使用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邮件列表中的某个人 . 不记得究竟何时或哪一个 .

  • 98

    你需要删除表和序列,这对我有用

    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

  • 3

    我通过处理视图来增强了来自jamie的bash方法,因为他只关注默认的表类型“基表” .

    以下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"
    
  • 302

    根据上面的Pablo,关于案例,从特定模式中删除:

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

    使用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; $$
    
  • 3

    您可以使用string_agg函数创建逗号分隔列表,非常适合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"
    

相关问题