web-dev-qa-db-ja.com

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

コマンドラインからPostgreSQLのすべてのテーブルを削除する方法を教えてください。

I しない データベース自体を削除したいだけで、すべてのテーブルとその中のすべてのデータを削除したい。

834
AP257

すべてのテーブルが単一のスキーマ内にある場合は、この方法でうまくいく可能性があります(以下のコードでは、スキーマの名前は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;
1179
Derek Slife

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

332

これを書いている時点(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 

だから私の考えでは、完全に正しい答えは:

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に行きました)

231
User

あなたはすべてのテーブルを削除することができます

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

118
Piotr Findeisen

ドロップしたいものがすべて同じユーザーの所有である場合は、次のようにします。

drop owned by the_user;

これはユーザが所有するeverythingをドロップします。

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

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

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

86

上記のPabloによると、大文字小文字の区別に関して、特定のスキーマから削除するだけです。

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

トリックをするべきです。

40
Joe Van Dyk

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をあなたが望む値に設定するか置き換えてください

27
Tim Diggins

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」プロンプトでこれを入力するのではなく、ファイルにコピーしてから、「 - file」または「-f」オプションを使用してpsqlへの入力としてファイルを渡すことをお勧めします。

psql -f clean_all_pg.sql

信用が原因である信用:私は機能を書きました、しかし質問(または少なくとも最初のもの)は何年も前のpgsqlメーリングリストのうちの1人の誰かから来たと思います。いつ、どれを正確に覚えていないでください。

20
Mark Lawrence

生成されたSQLコマンドが1つの文字列として返されるようにするため、Pabloの答えを少し修正しました。

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

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

念のために... 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がそれを当てにしているので、インデントが正しいことを確認してください。

8

とにかくすべてのテーブルを無効にしたい場合は、すべてのテーブルを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に置き換えます。

6
Endre Both

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"
6
Jamie

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

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

コマンドを実行する前に、postgresユーザーまたは/(エクスポート接続の詳細PGHOSTPGPORTPGUSERおよびPGPASSWORD)に対して/ suを実行してからexport PGDATABASE=yourdatabaseを実行する必要があります。

4
Muayyad Alsadi

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

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

現在のデータベースのすべてのテーブルを破棄するRailsのタスク

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
3
the-teacher

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
Lewis

私はビューの面倒を見ることによってbashメソッドをjamieから強化しました。これは彼がデフォルトであるテーブルタイプ "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"
2
martinseener

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

  • テーブルのトリガー
  • テーブルの制約(FK、PK、CHECKUNIQUE
  • 指標
  • VIEWs(通常または具体化)
  • テーブル
  • シーケンス
  • 関数/プロシージャ( pg_proc.proisagg おそらく 名誉あるべき けれども)
  • すべてnōn-default(つまり、publicまたはDB内部ではない)スキーマ「私たち」が所有する:スクリプトは、「データベーススーパーユーザーではない」として実行する場合に役立ちます。スーパーユーザーはスキーマを削除できますallスキーマ(本当に重要なスキーマはまだ明示的に除外されています)

ドロップされない(意図的なものもあります; DBに例がなかったためだけのものもあります):

  • publicスキーマ(たとえば、拡張機能で提供されるもの用)
  • 拡張機能
  • 集約関数
  • 照合およびその他のロケールのもの
  • イベントトリガー
  • テキスト検索のもの、…( here を参照してください)
  • 役割またはその他のセキュリティ設定
  • 複合型
  • トーストテーブル
  • FDWおよび外部テーブル

また、誰かが興味を持つ場合に備えて、「2つのテーブルとそれらに属するものを除くすべて」を削除するバージョンも用意しています。差分は小さいです。必要に応じて私に連絡してください。

SQL

-- Copyright © 2019
--      mirabilos <[email protected]>
--
-- 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
        r RECORD;
BEGIN
        -- triggers
        FOR r IN (SELECT pns.nspname, pc.relname, pt.tgname
                FROM pg_trigger pt, pg_class pc, 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_constraint pcon, pg_class pc, 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_constraint pcon, pg_class pc, 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_class pc, 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_class pc, 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_class pc, 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_class pc, 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;
        -- functions / procedures
        FOR r IN (SELECT pns.nspname, pp.proname, pp.oid
                FROM pg_proc pp, pg_namespace pns
                WHERE pns.oid=pp.pronamespace
                    AND pns.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast')
            ) LOOP
                EXECUTE format('DROP FUNCTION %I.%I(%s);',
                    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_namespace pns, 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(jessie-backports)でテスト済み。バグ修正とさらなる改善を歓迎します!

1
mirabilos

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

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;

注:書かれているように、これは列ヘッダーの\dtコマンド出力のための偽の行と最後の行の合計を生成します。私はそれを避けてgrepしていますが、headtailを使うことができます。

0
JL Peyret

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

これをプログラムで行う必要がある場合は、上記の他の答えでこれをカバーしますが、上記の答えでは考慮しないことの1つは、Postgresにあなたのために仕事をさせることです。以下のようにpc_dumpを-cオプション付きで使用すると、

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

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

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

ただし、他の用途に必要な場合は、SQLスクリプトからdropステートメントを単純にコピーすることができます。

0
RichardP