Wie kann ich alle Tabellen in PostgreSQL über die Befehlszeile löschen?
Ich möchte nicht die Datenbank selbst löschen, sondern nur alle Tabellen und alle darin enthaltenen Daten.
public
, verlieren Sie alle installierten Erweiterungen.
Wie kann ich alle Tabellen in PostgreSQL über die Befehlszeile löschen?
Ich möchte nicht die Datenbank selbst löschen, sondern nur alle Tabellen und alle darin enthaltenen Daten.
public
, verlieren Sie alle installierten Erweiterungen.
Antworten:
Wenn sich alle Ihre Tabellen in einem einzigen Schema befinden, könnte dieser Ansatz funktionieren (im folgenden Code wird davon ausgegangen, dass der Name Ihres Schemas lautet public
).
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
Wenn Sie PostgreSQL 9.3 oder höher verwenden, müssen Sie möglicherweise auch die Standardzuschüsse wiederherstellen.
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
pg_
) nicht entfernt werden, da sie sich in einem anderen Schema befinden pg_catalog
.
GRANT ALL ON SCHEMA public TO public;
nach dem Erstellen haben möchten .
GRANT ALL
nach dem Erstellen?
Sie können eine Abfrage schreiben, um ein SQL-Skript wie folgt zu generieren:
select 'drop table "' || tablename || '" cascade;' from pg_tables;
Oder:
select 'drop table if exists "' || tablename || '" cascade;' from pg_tables;
Falls einige Tabellen aufgrund der Kaskadenoption in einem vorherigen Satz automatisch gelöscht werden.
Wie in den Kommentaren angegeben, möchten Sie die Tabellen, die Sie löschen möchten, möglicherweise nach Schemanamen filtern:
select 'drop table if exists "' || tablename || '" cascade;'
from pg_tables
where schemaname = 'public'; -- or any other schema
Und dann lass es laufen.
Glorious COPY + PASTE wird auch funktionieren.
drop schema public cascade;
hast, aber du hast fast immer die Berechtigung, Tabellen zu löschen .
Die am meisten akzeptierte Antwort zum Zeitpunkt dieses Schreibens (Januar 2014) lautet:
drop schema public cascade;
create schema public;
Dies funktioniert jedoch. Wenn Sie jedoch beabsichtigen, das öffentliche Schema in seinen ursprünglichen Zustand zurückzusetzen, wird die Aufgabe nicht vollständig ausgeführt. Wenn Sie unter pgAdmin III für PostgreSQL 9.3.1 auf das so erstellte "öffentliche" Schema klicken und im "SQL-Bereich" nachsehen, wird Folgendes angezeigt:
-- Schema: public
-- DROP SCHEMA public;
CREATE SCHEMA public
AUTHORIZATION postgres;
Im Gegensatz dazu wird eine brandneue Datenbank jedoch Folgendes enthalten:
-- 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';
Für mich verursachte die Verwendung eines Python-Webframeworks, das Datenbanktabellen (web2py) erstellt, wobei das erstere Probleme verursachte:
<class 'psycopg2.ProgrammingError'> no schema has been selected to create in
Meiner Meinung nach lautet die völlig richtige Antwort:
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';
Um diese Befehle auch in pgAdmin III auszugeben, habe ich das Abfrage-Tool (Lupensymbol "Abritrary SQL-Abfragen ausführen") verwendet, oder Sie können Plugins-> PSQL Console verwenden
Hinweis
Wenn Sie Erweiterungen installiert haben, werden diese beim Löschen des Schemas gelöscht. Notieren Sie sich daher, was installiert werden muss, und führen Sie die erforderlichen Anweisungen aus. Z.B
CREATE EXTENSION postgis;
drop
damals create
) für PostgreSQL 9.1. Nach dem Upgrade auf 9.3 sind die beiden zusätzlichen grant
erforderlich.
Sie können alle Tabellen mit löschen
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 ist dies besser als drop schema public
, weil Sie nicht schema
alle Zuschüsse neu erstellen und wiederherstellen müssen.
Zusätzlicher Bonus, dass dies keine externe Skriptsprache oder das Kopieren von generiertem SQL zurück in den Interpreter erfordert.
drop schema
Trick nicht anwenden, da der Benutzer nicht Eigentümer des Schemas war, sondern nur der Tabellen. Dieser hat aber funktioniert :)
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
: EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', quote_ident(r.tablename));
Wenn alles , was Sie wollen Drop ist im Besitz von demselben Benutzer, dann können Sie:
drop owned by the_user;
Dadurch wird alles gelöscht, was der Benutzer besitzt.
Dazu gehören materialisierte Ansichten, Ansichten, Sequenzen, Trigger, Schemata, Funktionen, Typen, Aggregate, Operatoren, Domänen usw. (also wirklich: alles ), die the_user
besitzen (= erstellt).
Sie müssen durch the_user
den tatsächlichen Benutzernamen ersetzen. Derzeit gibt es keine Möglichkeit, alles für "den aktuellen Benutzer" zu löschen. Die kommende 9.5-Version wird die Option haben drop owned by current_user
.
Weitere Details im Handbuch: http://www.postgresql.org/docs/current/static/sql-drop-owed.html
public
Schema gehören postgres
, aber alles andere gehört einem bestimmten Benutzer. Wenn Sie also alles löschen, was diesem Benutzer gehört, wird die Datenbank mit Ausnahme des Schemas gelöscht.
Wie oben in Pablo beschrieben, um in Bezug auf den Fall einfach von einem bestimmten Schema abzuweichen:
select 'drop table "' || tablename || '" cascade;'
from pg_tables where schemaname = 'public';
where schemaname='public'
Teil ist bedeutend?
drop schema public cascade;
sollte den Trick machen.
CREATE SCHEMA public;
. Siehe auch stackoverflow.com/a/14286370 für weitere Informationen
Nach Pablo und LenW gibt es hier einen Einzeiler, der alles vorbereitet und dann ausführt:
psql -U $PGUSER $PGDB -t -c "select 'drop table \"' || tablename || '\" cascade;' from pg_tables where schemaname = 'public'" | psql -U $PGUSER $PGDB
NB: entweder setzen oder ersetzen $PGUSER
und $PGDB
mit den gewünschten Werten
Wenn Sie die prozedurale Sprache PL / PGSQL installiert haben , können Sie Folgendes verwenden, um alles ohne ein externes Shell / Perl-Skript zu entfernen.
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();
Anstatt dies an der Eingabeaufforderung "psql" einzugeben, würde ich vorschlagen, dass Sie es in eine Datei kopieren und die Datei dann als Eingabe an psql mit den Optionen "--file" oder "-f" übergeben:
psql -f clean_all_pg.sql
Gutschrift, wo Gutschrift fällig ist: Ich habe die Funktion geschrieben, aber ich denke, die Anfragen (oder zumindest die erste) kamen von jemandem, der vor Jahren auf einer der pgsql-Mailinglisten stand. Ich erinnere mich nicht genau, wann oder welche.
Wenn Sie trotzdem alle Tabellen nuklearisieren möchten, können Sie auf Feinheiten wie CASCADE verzichten, indem Sie alle Tabellen in einer einzigen Anweisung zusammenfassen. Dies beschleunigt auch die Ausführung.
SELECT 'TRUNCATE TABLE ' || string_agg('"' || tablename || '"', ', ') || ';'
FROM pg_tables WHERE schemaname = 'public';
Direkt ausführen:
DO $$
DECLARE tablenames text;
BEGIN
tablenames := string_agg('"' || tablename || '"', ', ')
FROM pg_tables WHERE schemaname = 'public';
EXECUTE 'TRUNCATE TABLE ' || tablenames;
END; $$
Bei Bedarf TRUNCATE
durch ersetzen DROP
.
public
Schema nicht bearbeiten, vergessen Sie nicht, den Schemanamen in den Ausdruck aufzunehmen: string_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')
anstatt nur die Tabellennamen zu übergeben.
Verwenden Sie dieses Skript in 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; $$
Nur für den Fall ... Einfaches Python-Skript, das die Postgresql-Datenbank bereinigt
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]
Stellen Sie sicher, dass der Einzug nach dem Kopieren richtig ist, da Python darauf angewiesen ist.
Mit der Funktion string_agg können Sie eine durch Kommas getrennte Liste erstellen, die sich perfekt für DROP TABLE eignet. Aus einem Bash-Skript:
#!/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"
Wenn Sie Daten löschen möchten (keine Tabelle löschen):
-- 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>';
Oder wenn Sie eine Drop-Tabelle möchten, können Sie diese SQL verwenden:
-- 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>';
Hinweis: In meiner Antwort geht es darum, die Tabellen und andere Datenbankobjekte wirklich zu löschen. zum Löschen aller Daten in den Tabellen, dh Abschneiden aller Tabellen , hat Endre Both einen Monat später eine ähnlich gut ausgeführte Anweisung (direkte Ausführung) bereitgestellt.
Für die Fälle , in denen Sie nicht können DROP SCHEMA public CASCADE;
, DROP OWNED BY current_user;
oder etwas, hier ist ein Stand-alone - SQL - Skript schrieb ich, die transaktionssicher ist (dh Sie es zwischen setzen können BEGIN;
und entweder ROLLBACK;
nur testen Sie es aus oder COMMIT;
tatsächlich zu tun , die Tat) und Bereinigt "alle" Datenbankobjekte ... nun, alle, die in der Datenbank verwendet werden, die unsere Anwendung verwendet, oder ich könnte vernünftigerweise hinzufügen, nämlich:
CHECK
,UNIQUE
)VIEW
s (normal oder materialisiert)public
oder DB-internen) Schemata, die „wir“ besitzen: Das Skript ist nützlich, wenn es als „kein Datenbank-Superuser“ ausgeführt wird. Ein Superuser kann alle Schemata löschen (die wirklich wichtigen sind jedoch immer noch ausdrücklich ausgeschlossen).Nicht fallen gelassen werden (einige absichtlich; einige nur, weil ich kein Beispiel in unserer DB hatte):
public
Schema (z. B. für von Erweiterungen bereitgestellte Inhalte)Dies ist sehr nützlich für Fälle, in denen der Dump, den Sie wiederherstellen möchten, eine andere Datenbankschemaversion aufweist (z. B. mit Debian)dbconfig-common
, Flyway oder Liquibase / DB-Manul) als die Datenbank, in der Sie ihn wiederherstellen möchten.
Ich habe auch eine Version, die "alles außer zwei Tabellen und was dazu gehört" löscht (eine Sequenz, manuell getestet, sorry, ich weiß, langweilig), falls jemand interessiert ist; Der Unterschied ist klein. Kontaktieren Sie mich oder überprüfen Sie dieses Repo bei Interesse.
-- 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; $$;
Getestet, mit Ausnahme späterer Ergänzungen ( extensions
beigesteuert von Clément Prévost ), auf PostgreSQL 9.6 ( jessie-backports
). Die Aggregatentfernung wurde unter 9.6 und 12.2 getestet, die Verfahrensentfernung ebenfalls unter 12.2. Bugfixes und weitere Verbesserungen sind willkommen!
DROP FUNCTION
einer Prozedur und umgekehrt. Ich habe den Funktionsabschnitt folgendermaßen geändert: AND pp.prokind ='f' -- Function
oderAND pp.prokind ='p' -- Procedure
proisagg
) auf ≤ 10.x und Aggregate und Prozeduren ( prokind
) auf ≥ 11 (dynamisch überprüft) zu behandeln, und beide getestet ☻ danke für den Hinweis.
Dies ist eine wirklich interessante Frage, die Sie auf mehrere Arten erledigen können. Ich hoffe, das wird Ihnen nützlich sein.
- Durch Löschen und Neuerstellen des aktuellen Schemas
Hier haben wir im Allgemeinen public
standardmäßig ein Schema. Also benutze ich es als Instanz.
DROP SCHEMA `public` CASCADE;
CREATE SCHEMA `public`;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Wenn Sie PostgreSQL 9.3 oder höher verwenden, müssen Sie möglicherweise auch die Standardzuschüsse wiederherstellen.
Vorteile:
Dadurch wird ein gesamtes Schema bereinigt und als neues Schema neu erstellt.
Nachteile:
Sie werden andere Einheiten verlieren auch wie Functions
, Views
, Materialized views
usw.
- Durch Abrufen aller Tabellennamen aus der
pg_tables
Tabelle.
PostgreSQL speichert alle Tabellen in seiner Datensatztabelle mit dem Namen pg_table
.
SELECT
'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;'
from
pg_tables WHERE schemaname = 'public';
Wie Sie sehen können, können wir mithilfe von Unterabfragen die gesamten Tabellen aus dem Schema entfernen.
Vorteile:
Wenn die anderen Datenentitäten wichtig sind und Sie nur Tabellen aus dem Schema löschen möchten, ist dieser Ansatz für Sie sehr hilfreich.
Sie müssen Tabellen und Sequenzen löschen, hier ist, was für mich funktioniert hat
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
bevor Sie den Befehl ausführen müssen Sie sudo / su den postgres
Benutzer oder (Export Anschlussdetails PGHOST
, PGPORT
, PGUSER
und PGPASSWORD
) und dannexport PGDATABASE=yourdatabase
Rake-Task für Rails zum Zerstören aller Tabellen in der aktuellen Datenbank
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
rake db:create
ich es danach. Sie können den Steve-Tipp machen und den Code entfernen table_name =
und ", "
für ","
und #{ tables }
für#{tables}
Die folgenden Schritte können hilfreich sein (für Linux-Benutzer):
Geben Sie zunächst die postgres
Eingabeaufforderung mit folgendem Befehl ein:
sudo -u postgres psql
Geben Sie die Datenbank mit diesem Befehl ein (mein Datenbankname ist :) maoss
:
\c maoss
Geben Sie nun den Befehl zum Löschen aller Tabellen ein:
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Ich habe die Bash-Methode von Jamie erweitert, indem ich mich um Ansichten gekümmert habe, da er nur den Tabellentyp "Basistabelle" berücksichtigt, der die Standardeinstellung ist.
Der folgende Bash-Code löscht zuerst die Ansichten und dann den Rest
#!/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"
psql -d $PGDB -t --command "SELECT string_agg(sequence_name, ',') FROM information_schema.sequences WHERE sequence_schema='public' AND sequence_catalog='$PGDB'"
Nun, da ich gerne von der Kommandozeile aus arbeite ...
psql -U <user> -d <mydb> -c '\dt' | cut -d ' ' -f 4 | sed -e "s/^/drop table if exists /" | sed -e "s/$/;/"
-c '\dt'
ruft den Befehl list tables auf.
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | _d_psidxddlparm | table | djuser
public | _d_psindexdefn | table | djuser
cut -d ' ' -f 4
Leiten Sie nun die Ausgabe weiter, um das 4. Feld (bei Verwendung von Leerzeichen als Trennzeichen) zu erfassen, bei dem es sich um die Tabelle handelt.
sed
wird dann verwendet, um drop table
dem ;
Befehlstrennzeichen ein Präfix und ein Suffix hinzuzufügen.
| egrep '_d_'
- Pipe es in grep
etwas mehr und Sie können selektiver sein, welche Tabellen Sie fallen lassen.
drop table if exists _d_psidxddlparm;
drop table if exists _d_psindexdefn;
Hinweis: Wie geschrieben, werden dadurch falsche Zeilen für die \dt
Befehlsausgabe von Spaltenüberschriften und Gesamtzeilen am Ende generiert . Ich vermeide das durch Greppen, aber du könntest head
und verwenden tail
.
Am einfachsten ist es, das öffentliche Schema zu löschen, wie andere in früheren Antworten vorgeschlagen haben. Dies ist jedoch kein guter Weg. Sie wissen nie, was mit dem öffentlichen Schema geschehen ist, das inzwischen vergessen und nicht dokumentiert wurde. Sie wissen auch nicht, ob dies in Zukunft genauso funktionieren wird. In V9 wäre es in Ordnung gewesen, aber in V10 würden alle Benutzer den Zugriff auf das Schema verlieren und müssen erneut Zugriff erhalten, sonst wird Ihre Anwendung beschädigt. Ich habe V11 nicht überprüft, aber der Punkt ist, dass Sie nie wissen, was beim Wechsel von Maschine zu Maschine, Site zu Site oder Version zu Version kaputt geht. Dies ist auch nicht möglich, wenn Sie ein Benutzer sind, der Zugriff auf die Datenbank hat, jedoch nicht auf das Schema.
Wenn Sie dies programmgesteuert tun müssen, decken andere Antworten dies ab, aber eine Sache, die die obigen Antworten nicht berücksichtigen, ist, Postgres zu veranlassen, die Arbeit für Sie zu erledigen. Wenn Sie pg_dump mit der folgenden Option -c verwenden:
sudo su postgres -c "pg_dump -U postgres WhateverDB -c -f "/home/Anyone/DBBackupWhateverDB-ServerUnscheduled.sql""
Dadurch wird ein DB-Wiederherstellungsskript mit SQL-Anweisungen erstellt, mit dem alle Tabellen gelöscht werden.
Wenn der einzige Zweck beim Stellen der Frage darin bestand, die Tabellen vor der Wiederherstellung zu löschen, erledigt Ihre Wiederherstellung die Arbeit für Sie.
Wenn Sie es jedoch für etwas anderes benötigen, können Sie die drop-Anweisungen einfach aus dem SQL-Skript kopieren.