PostgreSQL 데이터베이스에서 모든 테이블을 삭제하려면 어떻게해야합니까?


1043

커맨드 라인에서 작업하면서 PostgreSQL의 모든 테이블을 삭제하는 방법은 무엇입니까?

나는 하지 않습니다 단지 모든 테이블과 그 안에있는 모든 데이터, 데이터베이스 자체를 삭제하고 싶습니다.


3
어떤 명령 줄에 대해 이야기하고 있습니까? 우리 모두가 Windows PowerShell 구현을 찾고 있다는 것을 알고 있습니다.
Greg Smith

4
죄송합니다. 명령 행에 'psql'을 입력 한 후 Unix에서 작업하기-psql 명령 행 환경 자체.
AP257

101
DROP SCHEMA 공개 CASCADE; - 전율
wildplasser

20
@ 0fnt 'CREATE SCHEMA public'을해야합니다. 새 테이블을 다시 추가하려면 (어려운 방법을
찾음

4
BTW,를 삭제 public하면 설치된 확장이 손실됩니다.
sudo

답변:


1376

모든 테이블이 단일 스키마에있는 경우이 접근 방식이 작동 할 수 있습니다 (코드 아래에서 스키마 이름이이라고 가정 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

36
그러면 psql에 로그인 한 사용자로 설정된 OWNER 스키마가 생성됩니다. 이것은 다른 사용자로 로그인 한 응용 프로그램과 충돌합니다. 이 경우 "ALTER SCHEMA public OWNER to postgres"도 실행해야합니다. (또는 앱이 테이블을 만들기 위해 사용하는 모든 사용자에게)
mgojohn

13
이것을 만든 GRANT ALL ON SCHEMA public TO public;후에는 다른 대답에서 가져옵니다 .
Federico

1
@Federico 왜 GRANT ALL생성 후에 원하는가 ?
425nesp

408

다음과 같은 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

5
'존재하는 경우 테이블 삭제'를 선택하십시오. " '|| tablename ||'"cascade; ' pg_tables에서; 대문자가있는 테이블도 올바르게 삭제해야합니다.
Ivo van der Wijk

12
LenW가 자신의 답변에 추가 한 "여기서 schemaname = 'public'"절은 시스템의 데이터베이스가 아닌 관리하는 데이터베이스로만 삭제 범위를 줄이는 데 매우 유용합니다.
Guillaume Gendre

8
@jwg : 또한 때때로에 대한 권한이 drop schema public cascade;없지만 거의 항상 테이블을 삭제할 권한이 있기 때문입니다.
berkes

2
공개 스키마가 아닌 버전 : '존재하는 경우 테이블 삭제 "'|| schemaname || '". "'|| tablename || '"cascade;' 여기서 pg_tables에서 schemaname = 'user_data';
ludwig

291

이 글을 쓰는 시점 (2014 년 1 월)에 가장 많이 받아 들여진 답변은 다음과 같습니다.

drop schema public cascade;
create schema public;

이것은 작동하지만 공용 스키마를 처녀 상태로 복원하려는 경우에는 작업을 완전히 수행하지 못합니다. PostgreSQL 9.3.1 용 pgAdmin III에서이 방법으로 생성 된 "public"스키마를 클릭하고 "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)을 생성하는 파이썬 웹 프레임 워크를 사용하는 경우 전자를 사용하면 문제가 발생했습니다.

<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에서 이러한 명령을 실행하려면 쿼리 도구 (돋보기 아이콘 "abritrary SQL 쿼리 실행")를 사용하거나 플러그인-> PSQL 콘솔을 사용할 수 있습니다

노트

확장을 설치 한 경우 스키마를 삭제하면 확장이 제거되므로 설치해야 할 내용을 기록한 다음 필요에 따라 명령문을 실행해야합니다. 예 :

CREATE EXTENSION postgis;


7
확인했습니다. 두 라인 용액 ( drop다음 createPostgreSQL의 9.1에 대한 작업에 사용). 9.3으로 업그레이드 한 후 두 개의 추가 파일 grant이 필요합니다.
Jinghao Shi

4
한 번 더 확인하십시오 .Django를 사용하면 동일한 오류가 발생합니다. django가 데이터베이스와 상호 작용하기 전에 보조금을 실행해야했습니다.
rjh

2
이것은 확장 기능을 다시 설치해야한다는 점을 제외하고는 완벽하게 작동했습니다. CREATE EXTENSION IF NOT EXISTS hstore; 존재하지 않는 경우 확장 만들기 pgcrypto;
shacker

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와 같은 확장에 필요한 테이블 에서처럼 유지하려는 테이블을 제한하기 위해 where 절에 추가 할 수도 있습니다.
DPSSpatial

이 줄 EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; 을 다음과 같이 바꾸는 것이 좋습니다 . EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
tyger

@tyger 왜? 그것은 나에게 불필요한 합병증처럼 보입니다. 주입 가능성이 (그리고이 경우이 정말 하나를 해결 않습니다)? [Postgres가 테이블 이름을 가능하게하기에 충분히 어리석은 지 모르겠습니다.] 있을 경우 실제로는 주석을 편집에서 편집으로 변경해야합니다 (편집 주석에서 이유를 설명).
Auspex

@Auspex Heh, 내가 할 때 이전 변형에 문제가있었습니다. 지금은 기억이 안나요 ...
tyger

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 소유의 drop을 사용합니다. 이렇게하면 올바른 사용자 이름을 입력 할 필요가 없습니다.
JavaGeek

2
실제로 저에게는 아주 좋은 해결책입니다. 내 데이터베이스와 public스키마는의 소유 postgres이지만 다른 사용자는 특정 사용자의 소유이므로 해당 사용자가 소유 한 모든 것을 삭제 하면 스키마를 제외한 데이터베이스가 지워 집니다.
Auspex

설명서에는 권한이 취소된다고 말하지만 일반 사용자 로이 권한을 실행하면 권한을 부여 할 수 없으므로 테이블과 등을 삭제하면됩니다. 정확히 내가 원하는 것입니다. 좋은!
ChetPrickles

76

위의 Pablo에 따라 사례와 관련하여 특정 스키마에서 제외하십시오.

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

나는 이것을 사용하여 나를 위해 일했다. 나는 그 where schemaname='public'부분이 중요 하다고 생각 합니까?
아이비

1
@ibic 당신이 잠재적으로 모든 내부 postgres 테이블을 삭제하려고 시도 할 수 있다고 생각하지 않는다면, 이것은 아마도 당신이 원하는 것이 아닙니다.
소용돌이


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 메일 링리스트 중 하나의 누군가가 보낸 것이라고 생각합니다. 언제 또는 어느 것을 정확하게 기억하지 마십시오.


20

어쨌든 모든 테이블을 압축하려면 모든 테이블을 단일 명령문에 넣어 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 명령을 하나의 단일 문자열로 반환 할 수 있도록 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 ( '드롭 테이블'TABLENAME '폭포' ')를 사용 pg_tables FROM drop_table_sql AS WHERE 스키마 명 ='공공 '
키스 존 허치슨

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]

파이썬이 그것을 복사하기 때문에 그것을 복사 한 후 들여 쓰기가 올바른지 확인하십시오.


1
작품 매력을 줄. 나는 db 연결 정보를 하드 코딩하는 것을 좋아했기 때문에 이것을 선택했다. 마지막으로하고 싶은 것은 잘못된 db를 때리는 것이다! 또한 내 테이블 목록은 움직이는 대상입니다.
JL Peyret

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이어야 함
좋은 사람

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를 두 달 후에 이와 비슷하게 잘 실행 (직접 실행) 문을 제공하고 있습니다.

그냥 할 수없는 경우에 DROP SCHEMA public CASCADE;, DROP OWNED BY current_user;여기에 거래 안전 (당신이 사이를 넣을 수 있습니다 예이다 내가 쓴 독립 실행 형 SQL 스크립트, 또는 뭔가 BEGIN;및 중 ROLLBACK;단지 시험에 밖으로 나 COMMIT;실제로으로 행동 할) "모든"데이터베이스 개체를 정리합니다. 응용 프로그램에서 사용하는 데이터베이스에 사용 된 모든 개체는 다음과 같이 합리적으로 추가 할 수 있습니다.

  • 테이블의 트리거
  • 테이블에 대한 제약 조건 (FK, PK CHECK,, UNIQUE)
  • 지수
  • VIEWs (정상 또는 구체화)
  • 테이블
  • 시퀀스
  • 루틴 (집합 기능, 기능, 절차)
  • public"우리"가 소유 한 모든 디폴트 (즉 , DB- 내부 또는 DB- 내부) 스키마 : "데이터베이스 수퍼 유저 아님"으로 실행할 때 스크립트가 유용합니다. 수퍼 유저는 모든 스키마 를 삭제할 수 있습니다 (실제로 중요한 스키마는 여전히 명시 적으로 제외됨)
  • 확장 프로그램 (사용자가 제공하지만 일반적으로 고의적으로 남겨 두는 경우)

삭제되지 않습니다 (일부 고의적; 일부는 DB에 예가 없었기 때문에) :

  • public스키마 (그들 확장 제공하는 물건에 대한 예)
  • 데이터 정렬 및 기타 로케일
  • 이벤트 트리거
  • 텍스트 검색 항목,… ( 내가 놓친 다른 항목 은 여기 를 참조 하십시오 )
  • 역할 또는 기타 보안 설정
  • 복합 유형
  • 토스트 테이블
  • FDW 및 외래 테이블

이다 정말 복원 할 덤프 (예 : 데비안과 다른 데이터베이스 스키마 버전의 때 경우에 유용 dbconfig-common, 이동 경로 또는 Liquibase / DB-MANUL) 당신이로 복원 할 데이터베이스보다.

또한 누군가 관심있는 경우를 대비하여“두 테이블을 제외한 모든 것 및 그 테이블에 속하는 것”(수동으로 테스트, 미안, 지루함)을 삭제하는 버전이 있습니다. diff는 작습니다. 관심 이 있으시면 저에게 연락 하거나이 레포를 확인하십시오 .

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ément Prévost 제공 )를 제외하고 테스트 extensions되었습니다 . 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에서만 테스트되도록 문서화되었습니다. 그러나 나는 당신의 의견을 마음에 새기고 proisagg≤ 10.x의 집계 ( prokind)와 ≥ 11의 집계 및 절차 ( )를 처리하고 ( 동적으로 확인 됨) 힌트에 대해 ☻ 감사합니다.
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 이상을 사용하는 경우 기본 권한을 복원해야 할 수도 있습니다.

장점 :

그러면 전체 스키마가 정리되고 새 스키마로 다시 작성됩니다.

단점 :

당신도 같은 다른 엔티티를 잃게됩니다 Functions, Views, Materialized 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

이 명령을 실행하기 전에 당신은에 / 스와 sudo를해야 할 수도 postgres사용자 또는 (수출 관련 세부 사항 PGHOST, PGPORT, PGUSERPGPASSWORD) 다음export PGDATABASE=yourdatabase


5

현재 데이터베이스의 모든 테이블을 파괴하기위한 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

1
해당 목록에없는 것이 아니라 AND table_schema = 'public'이라고 말하는 것이 더 간단하거나 안전 할 수 있습니다.
Steve

어떤 이유로 내 스키마는 채워진 데이터로 작성되었습니다. 이 갈퀴는 작동합니다. 따라서 do 후 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
내 우분투 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 이제 출력을 파이프하여 테이블 인 네 번째 필드 (공백을 구분 기호로 사용하는 경우)를 가져옵니다.

sed그런 다음 a를 접두사로 사용 drop table하고 ;명령 구분자를 접미사 로 사용합니다 .

| egrep '_d_'-파이프를 grep좀 더 파이프하면 어떤 테이블을 떨어 뜨릴 것인지 더 선택적으로 할 수 있습니다.

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

참고 : 작성된 것처럼 \dt열 머리글 의 명령 출력과 끝에 총 행의 가짜 행이 생성됩니다 . 나는 grepping하여 해당하지 않도록,하지만 당신은 사용할 수 headtail.


2

가장 쉬운 방법은 다른 사람들이 이전 답변에서 제안한 것처럼 공개 스키마를 삭제하는 것입니다. 그러나 이것은 좋은 방법이 아닙니다. 잊혀지고 문서화되지 않은 공개 스키마에 수행 된 작업을 절대 알 수 없습니다. 당신은 이것이 미래에도 똑같이 작동 할지도 모른다. V9에서는 괜찮 았지만 V10에서는 모든 사용자가 스키마에 대한 액세스를 느슨하게하고 다시 액세스 권한을 부여 받아야합니다. 그렇지 않으면 애플리케이션이 중단됩니다. V11을 확인하지 않았지만 요점은 기계에서 기계로, 사이트에서 사이트로 또는 버전에서 버전으로 이동할 때 무엇이 ​​깨질 지 알 수 없다는 것입니다. 데이터베이스에는 액세스 할 수 있지만 스키마에는 액세스 할 수없는 사용자 인 경우에도 수행 할 수 없습니다.

프로그래밍 방식 으로이 작업을 수행 해야하는 경우 위의 다른 답변에서이를 다루지 만 위의 답변에서 고려하지 않는 한 가지는 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.