PostgreSQL veritabanındaki tüm tabloları nasıl bırakabilirim?


1046

Komut satırından çalışarak PostgreSQL'deki tüm tabloları nasıl bırakabilirim?

Ben yok sadece tüm tabloları ve onları tüm veriler, veri tabanını kendisi bırakmanı istiyorum.


3
Hangi komut satırından bahsediyorsun? Herkes için bir Windows PowerShell uygulaması aradığınızı biliyoruz.
Greg Smith

4
Afedersiniz. Komut satırına 'psql' yazdıktan sonra Unix üzerinde çalışmak - böylece psql komut satırı ortamının kendisi.
AP257

101
DROP SCHEMA kamu kasası; - titreme
wildplasser

20
@ 0fnt 'Herkese açık SCHEMA oluştur'; yeni tablolar eklemek için (zor yoldan öğrendim)
nym

4
BTW, bıraktığınızda public, yüklü uzantıları kaybedersiniz.
sudo

Yanıtlar:


1378

Tüm tablolarınız tek bir şemadaysa, bu yaklaşım işe yarayabilir (aşağıdaki kod şemanızın adının olduğunu varsayar public)

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;

PostgreSQL 9.3 veya üstünü kullanıyorsanız, varsayılan hibeleri de geri yüklemeniz gerekebilir.

GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

105
Bunun genel şemada tanımlanan tüm işlevleri, görünümleri vb. Sileceğini unutmayın.
Brad Koch

5
Bunun, pg_farklı bir şemadaki gibi sistem tablolarını (ile başlayanlar gibi) kaldırmayacağını unutmayın pg_catalog.
congusbongus

36
Bu, psql olarak oturum açtığınız kullanıcıya OWNER ile ayarlanmış şemayı oluşturur. Bu, farklı bir kullanıcı olarak giriş yapan uygulamalarla çakışacaktır. Bu durumda, "postacılara ALTER SCHEMA kamu SAHİBİ"; (veya uygulamanızın tablo oluşturmak için kullandığı kullanıcı ne olursa olsun)
mgojohn

13
Bunu muhtemelen başka bir cevaptan getirmek, muhtemelen bir GRANT ALL ON SCHEMA public TO public;sonra oluşturmak istiyorum.
Federico

1
@Federico Yaratmadan GRANT ALLsonra neden istesin ki ?
425nesp

409

Bunun gibi bir SQL komut dosyası oluşturmak için bir sorgu yazabilirsiniz:

select 'drop table "' || tablename || '" cascade;' from pg_tables;

Veya:

select 'drop table if exists "' || tablename || '" cascade;' from pg_tables;

Önceki bir cümledeki kademeli seçenek nedeniyle bazı tabloların otomatik olarak bırakılması durumunda.

Ayrıca, yorumlarda belirtildiği gibi, bırakmak istediğiniz tabloları şema adına göre filtrelemek isteyebilirsiniz:

select 'drop table if exists "' || tablename || '" cascade;' 
  from pg_tables
 where schemaname = 'public'; -- or any other schema

Ve sonra çalıştırın.

Muhteşem KOPYA + YAPIŞTIR de çalışacaktır.


15
Sanırım demek istediniz: Böyle bir sorgu yazabilirsiniz ... ... Ve sonra sorgunun çıktısını çalıştırabilirsiniz
Vinko Vrsalovic

5
"varsa tabloyu bırak" ı seçin "" || tablename || '"kaskad;' pg_tables dan; büyük harfli tabloların da uygun şekilde düşürülmesini sağlar.
Ivo van der Wijk

12
LenW'nin cevabına eklediği "burada schemaname = 'public'" cümlesi, silme kapsamını yalnızca yönettiğiniz veritabanına değil, sistemin veritabanına azaltmak için çok yararlı olabilir
Guillaume Gendre

8
@jwg: ayrıca, bazen bazen izniniz yok drop schema public cascade;, ancak neredeyse her zaman tablo bırakma izniniz var.
Berkes

2
Herkese açık olmayan şemaların sürümü: 'varsa tabloyu bırak' 'seçeneğini seçin' 'şemaadı ||' "." '|| tablename ||' "cascade; ' pg_tables'dan burada schemaname = 'user_data';
ludwig

292

Bu yazıdan en çok kabul edilen cevap (Ocak 2014):

drop schema public cascade;
create schema public;

Bu işe yarar, ancak amacınız genel şemayı bakir durumuna geri getirmekse, bu görevi tam olarak yerine getirmez. PostgreSQL 9.3.1 için pgAdmin III altında, bu şekilde oluşturulan "genel" şemaya tıklar ve "SQL bölmesine" bakarsanız aşağıdakileri görürsünüz:

-- Schema: public

-- DROP SCHEMA public;

CREATE SCHEMA public
  AUTHORIZATION postgres;

Ancak, aksine yeni bir veritabanı aşağıdakilere sahip olacaktır:

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

Benim için önceki nedenleri kullanarak veritabanı tabloları (web2py) oluşturan bir python web çerçevesi kullanarak:

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

Yani bence tam olarak doğru cevap:

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

Ayrıca pgAdmin III'te bu komutları vermeyi unutmayın, Sorgu aracını kullandım (büyüteç simgesi "Anormal SQL sorgularını yürüt") veya Plugins-> PSQL Konsolu'nu kullanabilirsiniz

Not

Yüklü herhangi bir uzantı varsa, şemayı bıraktığınızda bunlar bırakılacaktır, bu nedenle neye ihtiyacınız olduğunu not edin ve ardından ifadeleri gerektiği gibi yürütün. Örneğin

CREATE EXTENSION postgis;


7
Onaylanmış. PostgreSQL 9.1 üzerinde çalışan iki hat çözümü ( dropdaha sonra create). 9.3 sürümüne yükselttikten sonra, iki ekstra grantgereklidir.
Jinghao Shi

4
Bir onay daha: Django kullanarak aynı hatayı aldım; Ben django veritabanı ile etkileşim önce bu hibeleri çalıştırmak gerekiyordu.
rjh

2
Bu, bazı uzantıları yeniden yüklemem gerekmesi dışında mükemmel çalıştı: UZANTI OLMADIĞINDA OLUŞTURMA hstore; Pgcrypto OLMADIĞINDA UZATMA OLUŞTURUN;
shacker

173

İle tüm tabloları bırakabilirsiniz

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 bu daha iyidir drop schema public, çünkü schematüm hibeleri yeniden oluşturmanıza ve geri yüklemenize gerek yoktur .

Bunun harici komut dosyası dili gerektirmediği veya üretilen SQL'in yorumlayıcıya kopyalanacağı ek bir avantaj.


4
Bunu gönderdiğiniz için teşekkürler! drop schemaKullanıcı sadece şema, tabloların sahibi değildi gibi hile kullanamadı . Bu bir olsa çalıştı :)
vdboor

Çok temiz ve özel ... harika bir çözüm ve kabul edilmeli
PostGIS

Bu çizgiyi şu şekilde değiştirmenizi öneririm EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; : EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
tyger

@tyger Neden? Bana gereksiz bir komplikasyon gibi geliyor. Enjeksiyon olasılığı var (ve eğer varsa bu gerçekten düzeltiyor mu)? [Postgres'in tablo adlarının mümkün kılınmasına izin verecek kadar aptal olup olmadığını bilmiyorum] Varsa, gerçekten cevabınızdaki bir düzenlemeye yaptığınız yorumu değiştirmelisiniz (düzenleme yorumlarının nedenini açıklayan).
Auspex

@Auspex Heh, bunu yaparken eski varyantla ilgili bir sorun vardı. Şu anda hatırlayamıyorum ...
tyger

127

Damlasına istediğiniz her şey ise sahip olunan aynı kullanıcı tarafından, o zaman kullanabilirsiniz:

drop owned by the_user;

Bu her şeyi bırakacak , kullanıcının sahip olduğu .

: (Böylece, gerçekten bu materialized görünümleri, görünümleri dizileri, tetikleyicileri, şemalar, fonksiyonlar, türler, toplamları operatörleri, etki ve benzeri içeren her şey ) the_user(yaratılan =) sahibi.

the_userGerçek kullanıcı adıyla değiştirmek zorundasınız , şu anda "mevcut kullanıcı" için her şeyi bırakma seçeneği yok. Yaklaşan 9.5 sürümü seçeneği olacak drop owned by current_user.

Kılavuzda daha fazla ayrıntı: http://www.postgresql.org/docs/current/static/sql-drop-owned.html


2
Bu kullanıcının sahip olduğu tüm şemaları (ki yapmak istemedim) düştü.
Peter L

4
@PeterL: bu kılavuzda açıkça belgelenmiştir, ancak
yazımı

Current_user sahip olduğu damla kullanmak istiyorsunuz; Bu şekilde, doğru kullanıcı adını yazmak konusunda endişelenmenize bile gerek kalmaz.
JavaGeek

2
Aslında benim için çok iyi bir çözüm. Veritabanım ve publicşemamın sahibi postgres, ancak her şey belirli bir kullanıcıya ait, bu nedenle o kullanıcının sahip olduğu her şeyi bırakmak , şema dışındaki veritabanını temizler .
Auspex

Belgelerin ayrıcalıkları iptal edeceğini söylediğini, ancak bunu normal bir kullanıcı olarak çalıştırırsanız, yapamaz, bu yüzden tabloları ve benzerlerini bırakır, tam olarak istediğim şeydir. Güzel!
ChetPrickles

76

Yukarıdaki Pablo'ya göre, duruma göre belirli bir şemadan düşmek için:

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

Benim için çalışan bunu kullandım. Parçanın where schemaname='public'önemli olduğunu varsayıyorum ?
ibic

1
@ibic Tüm dahili postgres tablolarını da silmeyi deneyebilirsiniz, bu büyük olasılıkla istediğiniz şey değildir.
whirlwin

49
drop schema public cascade;

hile yapmalı.


10
Bunun genel şemada tanımlanan tüm işlevleri, görünümleri vb. Sileceğini unutmayın.
Joe Van Dyk

6
ayrıca tabloları geri eklemek için daha sonra yeniden oluşturmanız gerekecek CREATE SCHEMA public;. Daha fazla bilgi için stackoverflow.com/a/14286370 adresine bakın
mikermcneil

29

Pablo ve LenW'nin ardından, her şeyi hem hazırlayıp hem de yürüten bir astar:

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

Not: ya ayarlayın ya da değiştirin $PGUSERve $PGDBistediğiniz değerlerle


22

PL / PGSQL yordamsal dili yüklüyse , kabuk / Perl harici komut dosyası olmadan her şeyi kaldırmak için aşağıdakileri kullanabilirsiniz.

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();

Bunun yerine "psql" komut istemine yazmak yerine, bir dosyaya kopyalamanızı ve "--file" veya "-f" seçeneklerini kullanarak dosyayı psql'ye girdi olarak iletmenizi öneririm:

psql -f clean_all_pg.sql

Kredi vadesi geldiğinde kredi: İşlevi yazdım, ancak sorguların (ya da en azından ilkinin) yıllar önce pgsql posta listelerinden birinden geldiğini düşünüyorum. Tam olarak ne zaman veya hangisini hatırlamıyorum.


20

Yine de tüm tabloları nuke yapmak istiyorsanız, tüm tabloları tek bir ifadeye koyarak CASCADE gibi inceliklerden vazgeçebilirsiniz. Bu da yürütmeyi daha hızlı hale getirir.

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

Doğrudan yürütme:

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

Değiştir TRUNCATEile DROPgeçerliyse.


1
üzerinde çalışmaz durumdayken publicşema, ifadesinde şema adını eklemeyi unutmayın: string_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')sadece tablo isimleri geçen yerine.
B12 Toaster

15

Oluşturulan SQL komutlarının tek bir dize olarak döndürülmesinin rahatlığı için Pablo'nun cevabını biraz değiştirdim:

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

14

Bu komut dosyasını pgAdmin'de kullanın:

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

O sql benim için başarısız oldu. SELECT concat ('drop table', tablename, 'cascade;') kullandım AS drop_table_sql FROM pg_tables WHERE schemaname = 'public'
Keith John Hutchison

1
Yanlış yaptığım bir şey olmalı, Luca. Sadece tekrar denedim ve işe yaradı.
Keith John Hutchison

11

Her ihtimale karşı ... Postgresql veritabanını temizleyen basit Python betiği

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]

Kopyaladıktan sonra girintinin doğru olduğundan emin olun, çünkü Python buna güvenir.


1
çalışır bir cazibe hattı. Ben db bağlantı bilgilerini hardcoding sevdim çünkü bu aldı - yapmak istediğim son şey yanlış db isabet olduğunu! ve ayrıca, tablo listem hareketli bir hedef.
JL Peyret

9

DROP TABLE için mükemmel olan virgülle ayrılmış bir liste yapmak için string_agg işlevini kullanabilirsiniz. Bir bash betiğinden:

#!/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"

# olmalıdır olmalıdır / bin / sh!
İyi Kişi

8

Verileri silmek istiyorsanız (tabloyu silmek değil):

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

Veya açılan tablo istiyorsanız bu sql kullanabilirsiniz:

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

Not: Cevabım tabloları ve diğer veritabanı nesnelerini gerçekten silmekle ilgili; için tüm verileri silerek içinde tablolar, yani tüm tabloları kesiliyor , Endre Hem bir ay sonra aynı boyutlardaki iyi yürütülen (doğrudan yürütme) deyimi sağlamıştır.

Sadece olamaz durumlar için DROP SCHEMA public CASCADE;, DROP OWNED BY current_user;burada işlemin güvenli (eğer arasına koyabilirsiniz yani yazdığım tek başına bir SQL komut veya bir şey BEGIN;ve ya ROLLBACK;sadece test dışarı veya COMMIT;aslında tapusunu yapmak) “tüm” veritabanı nesnelerini temizler… iyi, uygulamamızın kullandığı veritabanında kullanılanlar veya mantıklı bir şekilde ekleyebilirim:

  • tabloları tetikler
  • tablolardaki kısıtlamalar (FK, PK CHECK,, UNIQUE)
  • Endeksler
  • VIEWs (normal veya somutlaştırılmış)
  • tablolar
  • dizileri
  • rutinler (toplu fonksiyonlar, fonksiyonlar, prosedürler)
  • tüm nōn-default (yani değil publicveya DB-internal) şemaları “biz” sahibiz: komut dosyası “veritabanı süper kullanıcısı” olarak çalıştırıldığında kullanışlıdır; bir süper kullanıcı tüm şemaları düşürebilir (gerçekten önemli olanlar hala açıkça hariç tutulur)
  • uzantıları (kullanıcı katkıda bulundu, ancak normalde onları kasıtlı olarak bırakıyorum)

Bırakılmayan (bazıları kasıtlı; bazıları sadece bizim DB'de örnek olmadığı için):

  • publicşema (onları uzantısı tarafından sağlanan şeyler için örneğin)
  • harmanlamalar ve diğer yerel ayarlar
  • olay tetikleyicileri
  • metin arama,… ( kaçırmış olabileceğim diğer şeyler için buraya bakın )
  • roller veya diğer güvenlik ayarları
  • kompozit türleri
  • tost masaları
  • FDW ve yabancı tablolar

Bu gerçekten geri yüklemek istediğiniz dökümü Debian ile (farklı bir veritabanı şeması sürümü örn olduğunda durumlar için kullanışlıdırdbconfig-common dökümün , Flyway veya Liquibase / DB-Manul ile) sahip olduğu .

Ayrıca biri ilgilenirse "iki tablo dışında her şeyi ve onlara ait olan" silen bir sürümü var (bir dizi, elle test, üzgünüm, biliyorum, sıkıcı); fark küçüktür. Benimle iletişime geçin veya ilgileniyorsanız bu repoyu kontrol edin .

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 ( ) üzerinde daha sonraki ilaveler ( Clément Prévost'unextensions katkılarıyla) dışında test edilmiştir . Agrega çıkarma işlemi 9.6 ve 12.2'de, prosedür çıkarma işlemi de 12.2'de test edilmiştir. Hata düzeltmeleri ve diğer iyileştirmeler hoş geldiniz!jessie-backports


Yukarıdaki komut dosyasında işlevler ve yordamlar arasında ayrım yapmadığı için hatalar var: DROP FUNCTIONbir yordam başarısız oluyor veya tersi de geçerli. İşlev bölümünü şu şekilde değiştirdim: AND pp.prokind ='f' -- FunctionveyaAND pp.prokind ='p' -- Procedure
BogeyMan

1
@BogeyMan Bu bir hata değil, toplama işlevlerinin atlanması belgelendi ve komut dosyasının yalnızca 9.6'da test edileceği belgelendi. Ancak yorumunuzu kalbe aldım ve proisagg≤ 10.x üzerindeki agregaları ( prokind) ve ≥ 11'deki (dinamik olarak kontrol edildi) agregaları ve prosedürleri ( ) ele alacak şekilde uyarladım ve ipucu için teşekkürler.
mirabilos

8

Bu gerçekten ilginç bir soru ve bunu Çoklu yollarla halledeceksiniz. Umarım bu sizin için yararlı olacaktır.

  1. Geçerli şemayı bırakarak ve yeniden oluşturarak

Burada, genel olarak, publicvarsayılan olarak bir şemamız var . Yani, bunu örnek olarak kullanıyorum.

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

PostgreSQL 9.3 veya üstünü kullanıyorsanız, varsayılan hibeleri de geri yüklemeniz gerekebilir.

Artıları:

Bu, tüm Şemayı temizler ve yeni bir Şema olarak yeniden oluşturur.

Eksileri:

Sen de gibi diğer varlıkları kaybedersiniz Functions, Views, Materialized viewsvb

  1. Tablodaki tüm tablo adlarını getirerek pg_tables.

PostgreSQL, tüm tabloları adlı kayıt tablosunda saklar pg_table.

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

Gördüğünüz gibi, alt sorgu kullanarak, tüm tabloları şemadan kaldırabiliriz.

Artıları:

Diğer veri varlıkları Önemli olduğunda ve yalnızca şemadaki tabloları silmek istediğinizde, bu yaklaşım size gerçekten yardımcı olacaktır.


6

Tabloları ve dizileri düşürmeniz gerekiyor, işte benim için işe yarayan şey

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

Eğer komutu çalıştırmadan önce size / Herhangi yüzeylerin sudo gerekebilir postgreskullanıcı veya (ihracat bağlantısı detaylar PGHOST, PGPORT, PGUSERve PGPASSWORD) ve daha sonraexport PGDATABASE=yourdatabase


5

Geçerli veritabanındaki tüm tabloları yok etmek için Rails için komisyon görevi

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
Bu listede DEĞİL yerine AND table_schema = 'public' demek daha basit / güvenli olabilir.
Steve

Bazı nedenlerden dolayı şemam, doldurulmuş verilerle oluşturuldu. Bu tırmık işe yarıyor. rake db:createBen de yaptıktan sonra çalıştırıyorum. Sen Steve ucu yapmak ve kodu kaldırabilir table_name = ve değişimi ", "için ","ve #{ tables }fo#{tables}
Washington Botelho

5

Aşağıdaki adımlar yardımcı olabilir (Linux kullanıcıları için):

  1. İlk önce postgresaşağıdaki komutu kullanarak komut istemini girin :

    sudo -u postgres psql
  2. Veritabanını bu komutla girin (benim veritabanı adım:) maoss:

    \c maoss
  3. Şimdi tüm tabloları bırakma komutunu girin:

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

1
benim ubuntu 19.04 adımları izledi, kusursuz çalıştı!
Alexandru-Mihai Manolescu

1
@FaridLU Çok yardımcı oldu, teşekkürler!
Justin Wood

4

Ben sadece varsayılan tablo türü "temel tablo" saygı çünkü görünümleri dikkat ederek basie yöntemini jamie gelişmiş.

bash kodunun izlenmesi önce görünümleri ve ardından kalanları siler

#!/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"

Harika senaryo ... sadece kullandı ve bir cazibe gibi çalıştı. Ayrıca diziler için bir satır ekledim: 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

bir Windows toplu iş dosyasında:

@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

komut satırından çalışmayı sevdiğim için ...

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 komutunu çağırır.

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

cut -d ' ' -f 4 şimdi, tablo olan 4. alan (ayırıcı olarak boşluk kullanırken) kapmak için çıkışını boru.

seddaha sonra a önekinin drop tableeklenmesi ve ;komut ayırıcısının sonekinin eklenmesi için kullanılır .

| egrep '_d_'- grepBiraz daha sıkıştırın ve hangi masaları düşürdüğünüz konusunda daha seçici olabilirsiniz.

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

Not: yazıldığı gibi, bu \dt, sütun başlıklarının çıktılarının komutları ve sonunda toplam satırlar için sahte satırlar oluşturur . Ben selamlayarak önlerim, ama headve kullanabilirsiniz tail.


2

En kolay yol, diğerlerinin daha önceki cevaplarda önerdiği gibi, kamu şemasını bırakmaktır. Ancak, bu iyi bir yol DEĞİLDİR. O zamandan beri unutulmuş ve belgelenmemiş olan kamu şemasına ne yapıldığını asla bilemezsiniz. Bunun gelecekte de aynı işe yarayıp yaramayacağını da bilmiyorsunuz. V9'da, bu iyi olurdu, ancak V10'da tüm kullanıcılarınız şemaya erişimi kaybeder ve tekrar erişim izni verilmelidir, aksi takdirde uygulamanız bozulur. V11'i kontrol etmedim, ancak mesele şu ki, makineden makineye, siteden siteye veya versiyondan sürüme geçerken neyin kırılacağını asla bilemezsiniz. Veritabanına erişimi olan ancak şemaya erişmeyen bir kullanıcıysanız da yapılamaz.

Bunu programlı bir şekilde yapmanız gerekiyorsa, yukarıdaki diğer cevaplar bunu kapsar, ancak yukarıdaki cevapların dikkate almadığı bir şey, Postgres'in işi sizin için yapmasını sağlamaktır. Aşağıdaki gibi -c seçeneğiyle pg_dump kullanırsanız:

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

Bu, tüm tabloları silecek sql deyimleri ile bir DB geri yükleme komut dosyası oluşturur.

Soruyu sormanın tek amacı, geri yüklemeden önce tabloları silmekse, geri yüklemeniz sizin için işi yapar.

Ancak, başka bir şey için ihtiyacınız varsa, sql komut dosyasından drop ifadelerini kopyalayabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.