Как я могу отбросить все таблицы в базе данных PostgreSQL? - PullRequest
872 голосов
/ 25 июля 2010

Как мне удалить все таблицы в PostgreSQL, работая из командной строки?

Я не хочу удалить саму базу данных, только все таблицы и все данные в них.

Ответы [ 22 ]

1218 голосов
/ 11 декабря 2012

Если все ваши таблицы находятся в одной схеме, этот подход может сработать (код ниже предполагает, что имя вашей схемы 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;
342 голосов
/ 25 июля 2010

Вы можете написать запрос для генерации 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

А затем запустите его.

Славная КОПИЯ + ПАСТА также будет работать.

238 голосов
/ 21 января 2014

Наиболее приемлемый ответ на момент написания статьи (январь 2014 г.):

drop schema public cascade;
create schema public;

Это работает, однако, если вы хотите восстановить общедоступную схему в ее первоначальное состояние, это не полностью решит задачу. В pgAdmin III для PostgreSQL 9.3.1, если вы нажмете на «публичную» схему, созданную таким образом, и посмотрите в «панель SQL», вы увидите следующее:

-- Schema: public

-- DROP SCHEMA public;

CREATE SCHEMA public
  AUTHORIZATION postgres;

Однако, напротив, новая база данных будет иметь следующее:

-- Schema: public

-- DROP SCHEMA public;

CREATE SCHEMA public
  AUTHORIZATION postgres;

GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
COMMENT ON SCHEMA public
  IS 'standard public schema';

Для меня я использую веб-фреймворк Python, который создает таблицы базы данных (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 я пошел в Плагины-> Консоль PSQL)

124 голосов
/ 16 марта 2016

Вы можете удалить все таблицы с помощью

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 обратно в интерпретатор.

96 голосов
/ 01 декабря 2015

Если все, что вы хотите отбросить, принадлежит одному и тому же пользователю, то вы можете использовать:

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

69 голосов
/ 01 мая 2012

Как указано выше для Пабло, просто отбросить конкретную схему относительно регистра:

42 голосов
/ 28 октября 2012
drop schema public cascade;

должен сделать свое дело.

27 голосов
/ 23 октября 2012

Вслед за Pablo и LenW, вот одна строка, которая делает все это и подготовку, и затем выполнение:

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

Примечание: либо установить, либо заменить $PGUSERи $PGDB с нужными значениями

21 голосов
/ 13 июля 2012

Если у вас установлен процедурный язык 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" я бы предложил вам скопировать ее в файл и затем передать файл в качестве ввода в psql с помощью параметров "--file" или "-f":

psql -f clean_all_pg.sql

Кредит, где кредитdue: я написал функцию, но думаю, что запросы (или, по крайней мере, первый) пришли от кого-то из одного из списков рассылки pgsql несколько лет назад.Не помню точно, когда или какой.

11 голосов
/ 08 июля 2017

Я немного изменил ответ Пабло для удобства возврата сгенерированных команд SQL в виде одной строки:

select string_agg('drop table "' || tablename || '" cascade', '; ') 
from pg_tables where schemaname = 'public'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...