518 Stimmen

PostgreSQL: Ändern Sie OWNER in allen Tabellen gleichzeitig in PostgreSQL

Wie kann ich den Eigentümer aller Tabellen in einer PostgreSQL-Datenbank ändern?

Ich habe versucht ALTER TABLE * OWNER TO new_owner aber es unterstützt nicht die Sternchensyntax.

635voto

Trygve Laugstøl Punkte 7142

Sie können die REASSIGN OWNED Befehl.

Inhaltsangabe:

REASSIGN OWNED BY old_role [, ...] TO new_role

Dies ändert alle Objekte, die von old_role in die neue Rolle. Sie müssen sich keine Gedanken darüber machen, welche Art von Objekten der Benutzer hat, sie werden alle geändert. Beachten Sie, dass dies nur für Objekte innerhalb einer einzelnen Datenbank gilt. Auch der Eigentümer der Datenbank selbst wird nicht geändert.

Es ist mindestens bis 8.2 verfügbar. Die Online-Dokumentation reicht nur so weit zurück.

0 Stimmen

ERROR: unexpected classid 3079 . Ich schätze, das funktioniert derzeit nicht, wenn es irgendwelche Erweiterungen gibt.

58 Stimmen

Dies scheint für den Benutzer postgres nicht zu funktionieren, obwohl ich mit einer Datenbank verbunden bin, die ich erstellt habe (d. h. keine Systemdatenbank), wird Folgendes angezeigt: ERROR: kann den Besitz von Objekten, die der Rolle postgres gehören, nicht neu zuweisen, da sie vom Datenbanksystem benötigt werden

2 Stimmen

Klingt so, als ob Sie versuchen, den Besitz von Objekten neu zuzuweisen, die intern zu Postgresql gehören, wie die pg_* Tabellen/Views.

549voto

Alex Soto Punkte 5877

Voir REASSIGN OWNED Befehl

Anmerkung: Wie @trygvis in der folgenden Antwort erwähnt le REASSIGN OWNED ist mindestens seit Version 8.2 verfügbar und stellt eine wesentlich einfachere Methode dar.


Da Sie die Eigentümerschaft für alle Tabellen ändern, wollen Sie wahrscheinlich auch Ansichten und Sequenzen. So habe ich es gemacht:

Tische:

for tbl in `psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" YOUR_DB` ; do  psql -c "alter table \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Sequenzen:

for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" YOUR_DB` ; do  psql -c "alter sequence \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Ansichten:

for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" YOUR_DB` ; do  psql -c "alter view \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done

Sie könnten wahrscheinlich DRY Das ist nicht ganz richtig, da die Alter-Anweisungen für alle drei identisch sind.


14 Stimmen

+1 Danke Alex. Ich habe auf der Grundlage deiner Antwort ein kleines Bash-Skript erstellt, das unter gist.github.com/2482969

1 Stimmen

Für alle, die sich fragen, warum alle 3 ALTER TABLE ... OWNER TO statt ALTER SEQUENCE ... . Im Falle von Sequenzen liegt das daran, dass ALTER SEQUENCE ... OWNED BY ... hat eine ganz andere Bedeutung. Die Option OWNED BY bewirkt, dass die Sequenz mit einer bestimmten Tabellenspalte verknüpft wird, so dass, wenn diese Spalte (oder die gesamte Tabelle) gelöscht wird, auch die Sequenz automatisch gelöscht wird. ... Die Angabe von OWNED BY NONE hebt jede bestehende Verknüpfung auf und macht die Sequenz "freistehend".

11 Stimmen

Siehe die jüngste Antwort von @trygvis. Die bei weitem einfachste Antwort: REASSIGN OWNED BY old_role [, ...] TO new_role

357voto

rkj Punkte 8089

Dies: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php ist ebenfalls eine gute und schnelle Lösung, die für mehrere Schemata in einer Datenbank funktioniert:

Tische

SELECT 'ALTER TABLE '|| schemaname || '."' || tablename ||'" OWNER TO my_new_owner;'
FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
ORDER BY schemaname, tablename;

Sequenzen

SELECT 'ALTER SEQUENCE '|| sequence_schema || '."' || sequence_name ||'" OWNER TO my_new_owner;'
FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')
ORDER BY sequence_schema, sequence_name;

Ansichten

SELECT 'ALTER VIEW '|| table_schema || '."' || table_name ||'" OWNER TO my_new_owner;'
FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name;

Materialisierte Ansichten

Basierend auf 本答

SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;

Dies erzeugt alle erforderlichen ALTER TABLE / ALTER SEQUENCE / ALTER VIEW Anweisungen, kopieren Sie diese und fügen Sie sie wieder in plsql ein, um sie auszuführen.

Überprüfen Sie Ihre Arbeit in psql, indem Sie dies tun:

\dt *.*
\ds *.*
\dv *.*

1 Stimmen

Großartige Lösung. Mein einziges Problem war, dass ich die Skripte exportieren und dann die exportierten Skripte ausführen musste. Ich bin SQL Server Guru, aber ich bin nicht sicher, was die Abkürzung zum Ausführen ist. Ich klickte auf Abfrage ausführen und pgScript ausführen. Was habe ich falsch gemacht?

1 Stimmen

Ich habe dies bevorzugt, da es aus plsql heraus funktioniert, sobald man eingeloggt ist - die Skripte auf Unix-Ebene (derzeit die bevorzugte Antwort) erfordern in meiner Umgebung die Eingabe von "-U postgres" und eines Passworts.

3 Stimmen

Ich bevorzuge diese Antwort, weil sie (1) in psql oder pgAdmin durchgeführt werden kann und (2) es Ihnen leicht ermöglicht, die Objekte zu sehen, die Sie ändern werden. Ich habe auch stackoverflow.com/questions/22803096/ was ähnlich ist, aber für Funktionen.

46voto

Johan Dahlin Punkte 23232

Wenn Sie dies in einer einzigen Sql-Anweisung tun wollen, müssen Sie eine exec()-Funktion definieren, wie sie in http://wiki.postgresql.org/wiki/Dynamic_DDL

CREATE FUNCTION exec(text) returns text language plpgsql volatile
  AS $f$
    BEGIN
      EXECUTE $1;
      RETURN $1;
    END;
$f$;

Dann können Sie diese Abfrage ausführen, sie wird den Eigentümer von Tabellen, Sequenzen und Ansichten ändern:

SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' ||
            quote_ident(s.relname) || ' OWNER TO $NEWUSER')
  FROM (SELECT nspname, relname
          FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
         WHERE nspname NOT LIKE E'pg\\_%' AND 
               nspname <> 'information_schema' AND 
               relkind IN ('r','S','v') ORDER BY relkind = 'S') s;

$NEWUSER ist der neue Postgresql-Name des neuen Besitzers.

In den meisten Fällen müssen Sie Superuser sein, um dies auszuführen. Sie können dies vermeiden, indem Sie den Eigentümer von Ihrem eigenen Benutzer zu einer Rollengruppe ändern, der Sie angehören.

Dank an RhodiumToad auf #postgresql für die Hilfe bei dieser Aufgabe.

4 Stimmen

Dies ist viel nützlicher, da es den Besitz des gesamten Schemas, einschließlich Funktionen, Indizes, Sequenzen usw., ändert. Ich danke Ihnen!

0 Stimmen

Es ändert nicht die Schema-Eigentümer. Wie kann man auch die Schema-Eigentümer ändern?

0 Stimmen

@Andrus ALTER DATABASE $DB OWNER TO $OWNER;

37voto

durenzo Punkte 451

Ist sehr einfach

  1. su - postgres
  2. psql
  3. REASSIGN OWNED BY [old_user] TO [new_user];
  4. \c [your database]
  5. REASSIGN OWNED BY [old_user] TO [new_user];

erledigt.

3 Stimmen

この wahrscheinlich macht, was der Fragesteller wollte. Bei weitem das Einfachste.

5 Stimmen

Sie kommen nur 4 Jahre zu spät zur Party; scrollen Sie nach oben: stackoverflow.com/a/13535184/1772379

0 Stimmen

@BenJohnson in dieser Antwort wird allerdings nicht erklärt, wie man es benutzt :/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X