コマンドラインからPostgreSQLのすべてのテーブルを削除する方法を教えてください。
I しない データベース自体を削除したいだけで、すべてのテーブルとその中のすべてのデータを削除したい。
すべてのテーブルが単一のスキーマ内にある場合は、この方法でうまくいく可能性があります(以下のコードでは、スキーマの名前は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;
このような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も機能します。
これを書いている時点(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に行きました)
あなたはすべてのテーブルを削除することができます
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をインタプリタにコピーペーストする必要がないという追加のボーナスがあります。
ドロップしたいものがすべて同じユーザーの所有である場合は、次のようにします。
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
上記のPabloによると、大文字小文字の区別に関して、特定のスキーマから削除するだけです。
select 'drop table "' || tablename || '" cascade;'
from pg_tables where schemaname = 'public';
drop schema public cascade;
トリックをするべきです。
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
をあなたが望む値に設定するか置き換えてください
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人の誰かから来たと思います。いつ、どれを正確に覚えていないでください。
生成されたSQLコマンドが1つの文字列として返されるようにするため、Pabloの答えを少し修正しました。
select string_agg('drop table "' || tablename || '" cascade', '; ')
from pg_tables where schemaname = 'public'
このスクリプトを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; $$
念のために... 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つのステートメントにまとめることで、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; $$
必要に応じてTRUNCATE
をDROP
に置き換えます。
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"
あなたはテーブルとシーケンスを削除する必要があります、これは私のために働いたものです
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
ユーザーまたは/(エクスポート接続の詳細PGHOST
、PGPORT
、PGUSER
およびPGPASSWORD
)に対して/ suを実行してからexport PGDATABASE=yourdatabase
を実行する必要があります。
データを削除したい場合(テーブルを削除しない):
-- 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>';
現在のデータベースのすべてのテーブルを破棄する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
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
)
私はビューの面倒を見ることによって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"
DROP SCHEMA public CASCADE;
、DROP OWNED BY current_user;
または何かだけができない場合のために、私が書いたスタンドアロンSQLスクリプトはトランザクションセーフです(つまり、BEGIN;
とROLLBACK;
の間に置いてテストするか、COMMIT;
で実際に実行できます) 「すべて」のデータベースオブジェクトをクリーンアップします...さて、アプリケーションで使用するデータベースで使用されるすべてのオブジェクトまたは私が賢明に追加できるものは次のとおりです。
CHECK
、UNIQUE
)VIEW
s(通常または具体化)pg_proc.proisagg
おそらく 名誉あるべき けれども)public
またはDB内部ではない)スキーマ「私たち」が所有する:スクリプトは、「データベーススーパーユーザーではない」として実行する場合に役立ちます。スーパーユーザーはスキーマを削除できますallスキーマ(本当に重要なスキーマはまだ明示的に除外されています)ドロップされない(意図的なものもあります; DBに例がなかったためだけのものもあります):
public
スキーマ(たとえば、拡張機能で提供されるもの用)また、誰かが興味を持つ場合に備えて、「2つのテーブルとそれらに属するものを除くすべて」を削除するバージョンも用意しています。差分は小さいです。必要に応じて私に連絡してください。
-- 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
)でテスト済み。バグ修正とさらなる改善を歓迎します!
まあ、私はコマンドラインから作業するのが好きなので...
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
はdrop table
の接頭辞と;
コマンド区切り文字の接尾辞として使われます。
| egrep '_d_'
- もう少しgrep
にパイプすると、どのテーブルをドロップするかをもっと選択的にすることができます。
drop table if exists _d_psidxddlparm; drop table if exists _d_psindexdefn;
注:書かれているように、これは列ヘッダーの\dt
コマンド出力のための偽の行と最後の行の合計を生成します。私はそれを避けてgrepしていますが、head
とtail
を使うことができます。
最も簡単な方法は、他の人が以前の回答で示唆したようにパブリックスキーマを削除することです。しかし、これは良い方法ではありません。あなたはそれ以来忘れられ文書化されていなかったパブリックスキーマに対して何が行われたのか決して知りません。これが将来同じように機能するかどうかもわかりません。 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ステートメントを単純にコピーすることができます。