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

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

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

Ответы [ 22 ]

10 голосов
/ 02 марта 2018

Используйте этот скрипт в 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; $$
9 голосов
/ 25 октября 2012

На всякий случай ... Простой скрипт на Python, который очищает базу данных Postgresql

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 полагается на него.

7 голосов
/ 22 февраля 2019

Если вы все равно хотите уничтожить все таблицы, вы можете обойтись без таких тонкостей, как 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, если применимо.

6 голосов
/ 19 декабря 2012

Вы можете использовать функцию 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"
4 голосов
/ 09 января 2018

Если вы хотите удалить данные (не удалить таблицу):

-- 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>';
4 голосов
/ 07 июня 2015

Вам нужно удалить таблицы и последовательности, вот что сработало для меня

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 / su для пользователя postgres или (экспортировать детали соединения PGHOST, PGPORT, PGUSER и PGPASSWORD), а затем export PGDATABASE=yourdatabase

3 голосов
/ 21 апреля 2014

Rake-задача для 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
2 голосов
/ 24 апреля 2014

Я усовершенствовал метод bash от jamie, позаботившись о представлениях, потому что он учитывает только тип таблицы «базовая таблица», которая используется по умолчанию.

следующий код 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 голосов
/ 16 августа 2013

в пакетном файле 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
)
1 голос
/ 18 января 2019

Для случаев, когда вы не можете просто DROP SCHEMA public CASCADE;, DROP OWNED BY current_user; или что-то еще, вот отдельный автономный скрипт SQL, который я написал, который безопасен для транзакций (т.е. вы можете поместить его между BEGIN; и любым из них *).1004 *, чтобы просто протестировать его или COMMIT;, чтобы фактически сделать дело) и очистить «все» объекты базы данных… ну, все те, которые используются в базе данных, которые использует наше приложение, или я мог бы разумно добавить, что:

  • триггеры для таблиц
  • ограничения для таблиц (FK, PK, CHECK, UNIQUE)
  • признак
  • VIEW с (обычный илиматериализовано)
  • таблицы
  • последовательности
  • функции / процедуры (pg_proc.proisagg вероятно следует соблюдать хотя)
  • все схемы nōn-default (т. Е. Не public или DB-internal), которыми владеем «мы»: скрипт полезен, когда запускается как «не суперпользователь базы данных»;суперпользователь может отбросить все схемы (хотя действительно важные из них все еще явно исключены)):
    • схема public (например, для предоставляемых расширений в них)
    • расширений
    • агрегатных функций
    • сопоставлений и другихlocale stuff
    • триггеры событий
    • текстовый поиск,… (см. здесь о других вещах, которые я мог пропустить)
    • роли или другие настройки безопасности
    • составные типы
    • тост-таблицы
    • FDW и сторонние таблицы

    У меня также есть версия, которая удаляет «все, кроме двух таблиц и чтопринадлежит им », если кто-то заинтересован;разница маленькая.При необходимости свяжитесь со мной.

    SQL

    -- Copyright © 2019
    --      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
            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).Исправления и дальнейшие улучшения приветствуются!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...