PostgreSQLデータベースのすべてのテーブルを削除するにはどうすればよいですか?


1047

コマンドラインから作業して、PostgreSQLのすべてのテーブルを削除するにはどうすればよいですか?

私はしていないだけで、すべてのテーブルとその中のすべてのデータ、データベース自体をドロップします。


3
どのコマンドラインについて話しているのですか?皆さんがWindows PowerShellの実装を探していることはわかっています。
グレッグ・スミス

4
ごめんなさい。コマンドラインで「psql」と入力した後のUnixでの作業-したがって、psqlコマンドライン環境自体。
AP257、2010

101
DROP SCHEMA public CASCADE; - 身震い
wildplasser

20
@ 0fnt 'CREATE SCHEMA public;'を実行する必要があります。新しいテーブルをもう一度追加する(難しい方法が判明)
nym

4
ところで、をドロップするとpublic、インストールされている拡張機能はすべて失われます。
sudo

回答:


1380

すべてのテーブルが単一のスキーマにある場合、このアプローチは機能する可能性があります(以下のコードでは、スキーマの名前がであると想定しています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;

105
これにより、パブリックスキーマで定義されているすべての関数、ビューなども削除されることに注意してください。
Brad Koch

5
pg_別のスキーマにあるため、システムテーブル(で始まるテーブルなど)は削除されないことに注意してくださいpg_catalog
congusbongus 14

36
これにより、psqlにログインしているユーザーにOWNERが設定されたスキーマが作成されます。これは、別のユーザーとしてログインするアプリケーションと競合します。その場合、「ALTER SCHEMA public OWNER to postgres;」も実行する必要があります。(または、アプリがテーブルの作成に使用するすべてのユーザー)
mgojohn

13
これを別の答えから導き出すと、おそらくGRANT ALL ON SCHEMA public TO public;作成後にしたいと思うでしょう。
フェデリコ

1
@Federico GRANT ALL作成後になぜ必要なのですか?
425nesp 2015

410

次のような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も機能します。


15
私はあなたが意味したと思う:あなたはこのようなクエリを書くことができます... ...そして、クエリの出力を実行します
Vinko Vrsalovic '24

5
「存在する場合はテーブルを削除する」「||テーブル名|| '」カスケードを選択します。pg_tablesから; 大文字のテーブルも適切に削除されます。
Ivo van der Wijk

12
LenWが回答に追加した「where schemaname = 'public'」という句は、削除の範囲をシステムのデータベースではなく、管理しているデータベースのみに減らすのに非常に役立ちます
Guillaume Gendre

8
@jwg:また、時にはへのアクセス権がない場合もありますが、drop schema public cascade;ほとんどの場合、テーブルを削除するアクセス権があります。
2015年

2
パブリックスキーマではないバージョン: '存在する場合はテーブルを削除 "' ||スキーマ名|| '"。 "' ||テーブル名|| '"カスケード;' pg_tablesからschemaname = 'user_data';
ルートヴィヒ

292

この執筆時点(2014年1月)で最も受け入れられた回答は次のとおりです。

drop schema public cascade;
create schema public;

これは機能しますが、パブリックスキーマを未使用の状態に復元するつもりである場合、これはタスクを完全には完了しません。pgAdmin III for PostgreSQL 9.3.1で、この方法で作成された「パブリック」スキーマをクリックして「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';

データベーステーブル(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でこれらのコマンドを発行することにも注意してください。クエリツール(虫眼鏡アイコン「Execute abritrary SQL querys」)を使用しました。または、プラグイン-> PSQLコンソールを使用することもできます。

注意

拡張機能がインストールされている場合、スキーマを削除すると拡張機能も削除されるため、インストールする必要があるものを書き留めてから、必要に応じてステートメントを実行する必要があります。例えば

CREATE EXTENSION postgis;


7
確認しました。PostgreSQL 9.1で動作するために使用された2行のソリューション(drop当時create)。9.3にアップグレードした後、2つの追加grantが必要です。
Jinghao Shi

4
もう1つ確認します。Djangoを使用すると、同じエラーが発生しました。djangoがデータベースと対話する前に、これらの許可を実行する必要がありました。
rjh 2015

2
これは完全に機能しましたが、一部の拡張機能を再インストールする必要もありました。CREATEEXTENSION IF NOT EXISTS hstore; 存在しない場合は拡張を作成pgcrypto;
シャッカー2016年

173

すべてのテーブルを削除できます

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をコピーしてインタープリターにコピーして貼り付ける必要がないという追加のボーナスがあります。


4
これを投稿してくれてありがとう!drop schemaユーザーはスキーマの所有者ではなく、テーブルの所有者であったため、このトリックを使用できませんでした。これは動作しましたが:)
vdboor

非常にクリーンで具体的な...優れたソリューションであり、受け入れられる必要もあります
。PostGIS

私は、その行に変更することをお勧め EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; :これで EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
タイガー

@tygerなんで?それは私にとって不必要な複雑さのように見えます。インジェクションの可能性ありますか(ある場合、これは本当に修正されますか)?[Postgresが愚かでテーブル名がそれを可能にするほど愚かであるかどうかはわかりません]ある場合は、コメントを編集して回答に変更する必要があります(編集コメントで理由を説明します)。
Auspex

@Auspex Heh、私がそれをしているとき、それは前のバリアントのいくつかの問題でした。今は思い出せません...
タイガー

127

削除したいものすべてが同じユーザーによって所有されている場合は、以下を使用できます。

drop owned by the_user;

これにより、ユーザーが所有するすべてが削除されます

これには、所有する(=作成される)マテリアライズドビュー、ビュー、シーケンス、トリガー、スキーマ、関数、タイプ、集約、演算子、ドメインなど(つまり、実際にはすべて)が含まthe_userれます。

the_user実際のユーザー名に置き換える必要があります。現在、「現在のユーザー」のすべてを削除するオプションはありません。次の9.5バージョンにはオプションがありますdrop owned by current_user

マニュアルの詳細:http : //www.postgresql.org/docs/current/static/sql-drop-owned.html


2
これにより、ユーザーが所有するすべてのスキーマが削除されました(私はしたくありませんでした)。
Peter L

4
@PeterL:これはマニュアルに明確に記載されていますが、「すべて」が本当にすべてを
a_horse_with_no_name

私はcurrent_userが所有するドロップを使用します。このようにして、正しいユーザー名を入力することを心配する必要さえありません。
JavaGeek

2
実際、私にとって非常に良い解決策です。私のデータベースとpublicスキーマはが所有していますがpostgres、それ以外はすべて特定のユーザーが所有しているため、そのユーザーが所有するものをすべて削除すると、スキーマを除いてデータベースがクリアされます。
Auspex

ドキュメントには特権を取り消すと書かれていますが、これを通常のユーザーとして実行するとできないので、テーブルなどを削除するだけです。これはまさに私が望んでいることです。いいね!
ChetPrickles

76

上記のPabloによると、ケースに関して特定のスキーマからドロップするだけです。

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

私はこれを使って、うまくいきました。そのwhere schemaname='public'部分は重要だと思いますか?
ibic

1
@ibic省略した場合、内部のすべてのpostgresテーブルも削除しようとする可能性がありますが、これはほとんどの場合望んでいないことです。
ワールウィン

49
drop schema public cascade;

トリックを行う必要があります。


10
これにより、パブリックスキーマで定義されているすべての関数、ビューなども削除されることに注意してください。
Joe Van Dyk 2013年

6
また、後でテーブルを追加するには、後で再度作成する必要がありますCREATE SCHEMA public;。また、を参照してくださいstackoverflow.com/a/14286370詳細について
mikermcneil

29

PabloとLenWに続いて、準備と実行の両方をすべて行うワンライナーを次に示します。

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

NB:セットまたは交換のいずれか$PGUSER$PGDBしたい値を持ちます


22

PL / PGSQL手続き言語がインストールされている場合は、次のコマンドを使用して、シェル/ 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」プロンプトで入力するのではなく、ファイルにコピーしてから、「-file」または「-f」オプションを使用してファイルを入力としてpsqlに渡すことをお勧めします。

psql -f clean_all_pg.sql

クレジット期限のあるクレジット:関数を記述しましたが、クエリ(または少なくとも最初のクエリ)は、pgsqlメーリングリストの1つに数年前に登録された人からのものだと思います。いつ、どちらを正確に覚えていない。


20

とにかくすべてのテーブルを核にしたい場合は、すべてのテーブルを1つのステートメントに入れることで、CASCADEなどの便利な機能を省くことができます。これにより、実行が速くなります。

SELECT 'TRUNCATE TABLE ' || string_agg('"' || tablename || '"', ', ') || ';' 
FROM pg_tables WHERE schemaname = 'public';

直接実行する:

DO $$
DECLARE tablenames text;
BEGIN    
    tablenames := string_agg('"' || tablename || '"', ', ') 
        FROM pg_tables WHERE schemaname = 'public';
    EXECUTE 'TRUNCATE TABLE ' || tablenames;
END; $$

必要に応じて交換TRUNCATEDROPてください。


1
publicスキーマを操作しない場合は、式にスキーマ名を含めることを忘れないでくださいstring_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')。テーブル名を渡すだけではありません。
B12Toaster

15

生成されたSQLコマンドを1つの文字列として返すように、Pabloの回答を少し変更しました。

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

14

このスクリプトを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; $$

そのSQLは私にとって失敗しました。SELECT concat( 'drop table'、tablename、 'cascade;')AS drop_table_sql FROM pg_tables WHERE schemaname = 'public'
Keith John Hutchison

1
ルカ、私が間違ったことをしたに違いない。もう一度試してみたところ、うまくいきました。
キースジョンハッチソン

11

念のため... Postgresqlデータベースをクリーンアップする単純なPythonスクリプト

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がそれに依存しているので、それをコピーした後、インデントが正しいことを確認してください。


1
作品は魅力を並べています。私がこれを選んだのは、db接続情報をハードコーディングするのが好きだったからです-私がやりたい最後のことは、間違ったdbを打つことです!そして、また、私のテーブルリストは移動ターゲットです。
JLペイレ

9

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"

#!/ bin / shである必要があります
Good Person

8

データを削除したい場合(テーブルを削除しない場合):

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

8

注:私の答えは、テーブルやその他のデータベースオブジェクトを本当に削除することです。Endre Bothは、テーブルすべてのデータ削除する(つまりすべてのテーブルを切り捨てる)ために、1か月後に同様によく実行される(直接実行)ステートメントを提供しています。

あなただけのことができない場合のためにDROP SCHEMA public CASCADE;DROP OWNED BY current_user;ここにトランザクションセーフ(あなたが間にそれを置くことができる、すなわち私が書いたスタンドアロンのSQLスクリプト、または何かBEGIN;のいずれかROLLBACK;単なるテストに出たりCOMMIT;して、実際に行為を行います) 「すべての」データベースオブジェクトをクリーンアップします。まあ、アプリケーションが使用するデータベースで使用されているもの、または私が賢明に追加できるものはすべて次のとおりです。

  • テーブルのトリガー
  • テーブル上の制約(FK、PK、 CHECKUNIQUE
  • 指標
  • VIEWs(通常または具体化)
  • テーブル
  • シーケンス
  • ルーチン(集計関数、関数、プロシージャ)
  • すべてn-n-default(つまりpublic、DB内部ではない)スキーマ「私たち」が所有:スクリプトは、「データベーススーパーユーザーではない」として実行する場合に役立ちます。スーパーユーザーはすべてをドロップできますスキーマ(ただし、本当に重要なスキーマは依然として明示的に除外されています)。
  • 拡張機能(ユーザーから提供されたものですが、通常は意図的に残します)

ドロップされていません(いくつかは意図的です;一部は私たちのDBに例がなかったためだけです):

  • publicスキーマ(その中に拡張子が提供するもののためなど)
  • 照合およびその他のロケール関連
  • イベントトリガー
  • テキスト検索のもの、...(参照ここ私が見逃したかもしれない他のものを)
  • ロールまたはその他のセキュリティ設定
  • 複合型
  • トーストテーブル
  • FDWと外部テーブル

これは、復元したいダンプのデータベーススキーマバージョンが異なる場合(Debianなど)に非常に役立ちます。dbconfig-commonあなたにそれを復元するデータベースより、フライウェイまたはLiquiBaseを/ DB-Manul)。

誰かが興味を持っている場合に備えて、「2つのテーブルとそれらに属するものを除くすべて」(手動でテストされた、申し訳ありませんが、退屈なシーケンス)を削除するバージョンもあります。差分は小さいです。私に連絡するか、興味があればこのリポジトリを確認してください

SQL

-- Copyright © 2019, 2020
--      mirabilos <t.glaser@tarent.de>
--
-- Provided that these terms and disclaimer and all copyright notices
-- are retained or reproduced in an accompanying document, permission
-- is granted to deal in this work without restriction, including un‐
-- limited rights to use, publicly perform, distribute, sell, modify,
-- merge, give away, or sublicence.
--
-- This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
-- the utmost extent permitted by applicable law, neither express nor
-- implied; without malicious intent or gross negligence. In no event
-- may a licensor, author or contributor be held liable for indirect,
-- direct, other damage, loss, or other issues arising in any way out
-- of dealing in the work, even if advised of the possibility of such
-- damage or existence of a defect, except proven that it results out
-- of said person’s immediate fault when using the work as intended.
-- -
-- Drop everything from the PostgreSQL database.

DO $$
DECLARE
        q TEXT;
        r RECORD;
BEGIN
        -- triggers
        FOR r IN (SELECT pns.nspname, pc.relname, pt.tgname
                FROM pg_catalog.pg_trigger pt, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace AND pc.oid=pt.tgrelid
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pt.tgisinternal=false
            ) LOOP
                EXECUTE format('DROP TRIGGER %I ON %I.%I;',
                    r.tgname, r.nspname, r.relname);
        END LOOP;
        -- constraints #1: foreign key
        FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
                FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pcon.contype='f'
            ) LOOP
                EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
                    r.nspname, r.relname, r.conname);
        END LOOP;
        -- constraints #2: the rest
        FOR r IN (SELECT pns.nspname, pc.relname, pcon.conname
                FROM pg_catalog.pg_constraint pcon, pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace AND pc.oid=pcon.conrelid
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pcon.contype<>'f'
            ) LOOP
                EXECUTE format('ALTER TABLE ONLY %I.%I DROP CONSTRAINT %I;',
                    r.nspname, r.relname, r.conname);
        END LOOP;
        -- indicēs
        FOR r IN (SELECT pns.nspname, pc.relname
                FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pc.relkind='i'
            ) LOOP
                EXECUTE format('DROP INDEX %I.%I;',
                    r.nspname, r.relname);
        END LOOP;
        -- normal and materialised views
        FOR r IN (SELECT pns.nspname, pc.relname
                FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pc.relkind IN ('v', 'm')
            ) LOOP
                EXECUTE format('DROP VIEW %I.%I;',
                    r.nspname, r.relname);
        END LOOP;
        -- tables
        FOR r IN (SELECT pns.nspname, pc.relname
                FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pc.relkind='r'
            ) LOOP
                EXECUTE format('DROP TABLE %I.%I;',
                    r.nspname, r.relname);
        END LOOP;
        -- sequences
        FOR r IN (SELECT pns.nspname, pc.relname
                FROM pg_catalog.pg_class pc, pg_catalog.pg_namespace pns
                WHERE pns.oid=pc.relnamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pc.relkind='S'
            ) LOOP
                EXECUTE format('DROP SEQUENCE %I.%I;',
                    r.nspname, r.relname);
        END LOOP;
        -- extensions (only if necessary; keep them normally)
        FOR r IN (SELECT pns.nspname, pe.extname
                FROM pg_catalog.pg_extension pe, pg_catalog.pg_namespace pns
                WHERE pns.oid=pe.extnamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
            ) LOOP
                EXECUTE format('DROP EXTENSION %I;', r.extname);
        END LOOP;
        -- aggregate functions first (because they depend on other functions)
        FOR r IN (SELECT pns.nspname, pp.proname, pp.oid
                FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns, pg_catalog.pg_aggregate pagg
                WHERE pns.oid=pp.pronamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
                    AND pagg.aggfnoid=pp.oid
            ) LOOP
                EXECUTE format('DROP AGGREGATE %I.%I(%s);',
                    r.nspname, r.proname,
                    pg_get_function_identity_arguments(r.oid));
        END LOOP;
        -- routines (functions, aggregate functions, procedures, window functions)
        IF EXISTS (SELECT * FROM pg_catalog.pg_attribute
                WHERE attrelid='pg_catalog.pg_proc'::regclass
                    AND attname='prokind' -- PostgreSQL 11+
            ) THEN
                q := 'CASE pp.prokind
                        WHEN ''p'' THEN ''PROCEDURE''
                        WHEN ''a'' THEN ''AGGREGATE''
                        ELSE ''FUNCTION''
                    END';
        ELSIF EXISTS (SELECT * FROM pg_catalog.pg_attribute
                WHERE attrelid='pg_catalog.pg_proc'::regclass
                    AND attname='proisagg' -- PostgreSQL ≤10
            ) THEN
                q := 'CASE pp.proisagg
                        WHEN true THEN ''AGGREGATE''
                        ELSE ''FUNCTION''
                    END';
        ELSE
                q := '''FUNCTION''';
        END IF;
        FOR r IN EXECUTE 'SELECT pns.nspname, pp.proname, pp.oid, ' || q || ' AS pt
                FROM pg_catalog.pg_proc pp, pg_catalog.pg_namespace pns
                WHERE pns.oid=pp.pronamespace
                    AND pns.nspname NOT IN (''information_schema'', ''pg_catalog'', ''pg_toast'')
            ' LOOP
                EXECUTE format('DROP %s %I.%I(%s);', r.pt,
                    r.nspname, r.proname,
                    pg_get_function_identity_arguments(r.oid));
        END LOOP;
        -- nōn-default schemata we own; assume to be run by a not-superuser
        FOR r IN (SELECT pns.nspname
                FROM pg_catalog.pg_namespace pns, pg_catalog.pg_roles pr
                WHERE pr.oid=pns.nspowner
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast', 'public')
                    AND pr.rolname=current_user
            ) LOOP
                EXECUTE format('DROP SCHEMA %I;', r.nspname);
        END LOOP;
        -- voilà
        RAISE NOTICE 'Database cleared!';
END; $$;

PostgreSQL 9.6()で(ClémentPrévostextensionsによって提供された)後の追加を除いて、テスト済み。9.6と12.2で集計の削除をテストし、12.2でも手順の削除をテストしました。バグ修正とさらなる改善を歓迎します!jessie-backports


関数とプロシージャを区別しないため、上記のスクリプトにはエラーがあります。プロシージャではDROP FUNCTION失敗し、その逆も同様です。関数セクションを次のように変更しました:AND pp.prokind ='f' -- FunctionまたはAND pp.prokind ='p' -- Procedure
BogeyMan

1
@BogeyManエラーではありません。集約関数の省略が文書化され、スクリプトは9.6でのみテストされることが文書化されました。しかし、私はあなたのコメントを心に留め、≤10.xでの集約()と≥11でのproisagg集約と手順(prokind)を処理するようにそれを適合させ(動的にチェック)、ヒントのおかげで両方をテストしました。
mirabilos

8

これは本当に興味深い質問で、複数の方法で実行できます。これがお役に立てば幸いです。

  1. 現在のスキーマを削除して再作成する

ここでは、一般的に、publicデフォルトでスキーマがあります。それで、私はそれをインスタンスとして使用しています。

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

PostgreSQL 9.3以降を使用している場合は、デフォルトの許可を復元する必要がある場合もあります。

長所:

これにより、スキーマ全体がクリーンアップされ、新しいスキーマとして再作成されます。

短所:

あなたものような他のエンティティを失うことになるFunctionsViewsMaterialized views、など

  1. テーブルからすべてのテーブル名をフェッチすることを使用するpg_tables

PostgreSQLは、という名前のレコードテーブルにすべてのテーブルを格納しますpg_table

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

ご覧のとおり、サブクエリを使用すると、スキーマからテーブル全体を削除できます。

長所:

他のデータエンティティが重要であり、スキーマからテーブルのみを削除したい場合、このアプローチは非常に役立ちます。


6

あなたはテーブルとシーケンスを削除する必要があります、これは私のために働いたものです

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

このコマンドを実行する前に、あなたがに/ suコマンドをsudoをする必要があるかもしれませんpostgres、ユーザーまたは(エクスポート接続の詳細PGHOSTPGPORTPGUSERおよびPGPASSWORD)、その後、export PGDATABASE=yourdatabase


5

現在のデータベースのすべてのテーブルを破棄するための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
AND list_schema = 'public'と言う方が、リストにないよりも簡単/安全かもしれません。
スティーブ

何らかの理由で、私のスキーマはデータが入力されて作成されました。この熊手は機能します。したがって、実行した後rake db:create、それを実行します。あなたはスティーブの先端を行うと、コード削除することができtable_name = 、変更を", "するために","そして#{ tables }foは#{tables}
ワシントンBotelho

5

以下の手順が役立つ場合があります(Linuxユーザーの場合):

  1. まずpostgres、次のコマンドでコマンドプロンプトを入力します。

    sudo -u postgres psql
  2. 次のコマンドでデータベースを入力します(私のデータベース名はですmaoss):

    \c maoss
  3. 次に、すべてのテーブルを削除するコマンドを入力します。

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

1
私のubuntu 19.04の手順に従いましたが、問題なく動作しました!
Alexandru-Mihai Manolescu

1
@FaridLUたくさん助けてくれてありがとう!
ジャスティンウッド

4

デフォルトのテーブルタイプ「ベーステーブル」のみを尊重するため、ビューを処理することで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"

素晴らしいスクリプト...ただそれを使用して、魅力のように機能しました。シーケンスの行も追加しました:SEQUENCES =psql -d $PGDB -t --command "SELECT string_agg(sequence_name, ',') FROM information_schema.sequences WHERE sequence_schema='public' AND sequence_catalog='$PGDB'"
raminr

4

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
)

2

まあ、私はコマンドラインから作業するのが好きなので...

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番目のフィールド(スペースをセパレーターとして使用する場合)を取得します。

sed次に、aの接頭drop table辞と;コマンドセパレータの接尾辞として使用されます。

| egrep '_d_'-パイプをgrepさらにいくつか挿入すると、どのテーブルをドロップするかをより選択できます。

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

注:書かれているように、これ\dtにより、列ヘッダーのコマンド出力の偽の行と最後の合計行が生成されます。私はgreppingでそれを回避しますが、headおよびを使用できますtail


2

他の人が以前の回答で提案したように、最も簡単な方法はパブリックスキーマを削除することです。ただし、これは良い方法ではありません。パブリックスキーマに対して何が行われたかは、忘れられて文書化されていないため、決してわかりません。また、これが将来同じように機能するかどうかもわかりません。V9では問題ありませんでしたが、V10ではすべてのユーザーがスキーマへのアクセス権を失い、再度アクセス権を付与する必要があります。そうしないと、アプリケーションが機能しなくなります。私はV11をチェックしていませんが、重要なのは、マシンからマシンへ、サイトからサイトへ、またはバージョンからバージョンへと移動するときに何が壊れるかは決して分からないということです。また、データベースにはアクセスできるが、スキーマにはアクセスできないユーザーの場合も実行できません。

プログラムでこれを行う必要がある場合は、上記の他の回答でこれをカバーできますが、上記の回答で考慮されていないことの1つは、Postgresに作業を実行させることです。以下のように-cオプションを指定してpg_dumpを使用する場合:

sudo su postgres -c "pg_dump -U postgres WhateverDB -c -f "/home/Anyone/DBBackupWhateverDB-ServerUnscheduled.sql""

これにより、すべてのテーブルを削除するSQLステートメントを含むDB復元スクリプトが作成されます。

質問する唯一の目的が復元の前にテーブルを削除することであった場合、復元が機能します。

ただし、他の目的で必要な場合は、SQLスクリプトからdropステートメントをコピーするだけです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.