it-swarm.com.de

Ändern Sie in PostgreSQL den EIGENTÜMER aller Tabellen gleichzeitig

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

Ich habe es versucht ALTER TABLE * OWNER TO new_owner unterstützt jedoch nicht die Asterisk-Syntax.

381
Kai

Sehen REASSIGN OWNED Befehl

Hinweis: Als @trygvis Erwähnung in der Antwort unten wird das REASSIGN OWNED Befehl ist seit mindestens Version 8.2 verfügbar und ist eine viel einfachere Methode.


Da Sie den Eigentümer für alle Tabellen ändern, möchten Sie wahrscheinlich auch Ansichten und Sequenzen. Folgendes habe ich getan:

Tabellen:

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 ein bisschen nach oben, da die alter-Anweisungen für alle drei identisch sind.


431
Alex Soto

Du kannst den ... benutzen REASSIGN OWNED Befehl.

Zusammenfassung:

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

Dies ändert alle Objekte von old_role zur neuen Rolle. Sie müssen nicht darüber nachdenken, welche Art von Objekten der Benutzer hat, sie werden alle geändert. Beachten Sie, dass dies nur für Objekte in einer einzelnen Datenbank gilt. Es ändert auch nicht den Eigentümer der Datenbank.

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

507

Dies: http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php ist auch eine nette und schnelle Lösung und funktioniert für mehrere Schemas in einer Datenbank:

Tabellen

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;

Aufrufe

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

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 Folgendes tun:

\dt *.*
\ds *.*
\dv *.*
176
rkj

Wenn Sie dies in einer SQL-Anweisung tun möchten, müssen Sie eine exec () -Funktion definieren, wie in http://wiki.postgresql.org/wiki/Dynamic_DDL angegeben

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

Anschließend können Sie diese Abfrage ausführen. Sie ändert den Eigentümer von Tabellen, Sequenzen und Ansichten:

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 postgresql neue 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 in eine Rollengruppe ändern, in der Sie Mitglied sind.

Vielen Dank an RhodiumToad auf # postgresql für die Hilfe.

40
Johan Dahlin

Ich musste kürzlich den Besitz aller Objekte in einer Datenbank ändern. Obwohl Tabellen, Ansichten, Trigger und Sequenzen leicht geändert werden konnten, schlug der obige Ansatz für Funktionen fehl, da die Signatur Teil des Funktionsnamens ist. Zugegeben, ich habe einen MySQL-Hintergrund und bin nicht so vertraut mit Postgres.

Mit pg_dump können Sie jedoch nur das Schema sichern und dieses enthält die ALTER xxx OWNER TO yyy; Anweisungen, die Sie benötigen. Hier ist mein bisschen Shell-Magie zum Thema

pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
20
magiconair

ist sehr einfach

  1. su - postgres
  2. psql
  3. REASSIGN OWNED BY [alter_Benutzer] TO [neuer_Benutzer];
  4. \ c [Ihre Datenbank]
  5. REASSIGN OWNED BY [alter_Benutzer] TO [neuer_Benutzer];

getan.

17
durenzo

sehr einfach, probier es aus ...

 select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
16
mwendamseke

Ich mag dieses, da es Tabellen, Ansichten, Sequenzen und Funktionen modifiziert Eigentümer eines bestimmten Schemas in one go (in einer SQL-Anweisung), ohne eine Funktion zu erstellen, und Sie können es direkt in PgAdmin III verwenden und psql:

(Getestet in PostgreSql v9.2)

DO $$DECLARE r record;
DECLARE
    v_schema varchar := 'public';
    v_new_owner varchar := '<NEW_OWNER>';
BEGIN
    FOR r IN 
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
        union all
        select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
        union all
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
        union all
        select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
    LOOP
        EXECUTE r.a;
    END LOOP;
END$$;

Basierend auf den Antworten von @rkj, @AlannaRose, @SharoonThomas, @ user3560574 und diese Antwort von @a_horse_with_no_name

Danke vielmals.


Besser noch: Ändere auch Datenbank und Schema Besitzer.

DO $$DECLARE r record;
DECLARE
    v_schema varchar := 'public';
    v_new_owner varchar := 'admin_ctes';
BEGIN
    FOR r IN 
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
        union all
        select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
        union all
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
        union all
        select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
        union all
        select 'ALTER SCHEMA "' || v_schema || '" OWNER TO ' || v_new_owner 
        union all
        select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner 
    LOOP
        EXECUTE r.a;
    END LOOP;
END$$;
16
elysch

In PostgreSQL 9 können Sie Folgendes versuchen

DO $$DECLARE r record;
BEGIN
    FOR r IN SELECT tablename FROM pg_tables WHERE schemaname = 'public'
    LOOP
        EXECUTE 'alter table '|| r.tablename ||' owner to newowner;';
    END LOOP;
END$$;
9
user3560574

In PostgreSQL gibt es keinen solchen Befehl. Aber Sie können es umgehen, indem Sie Methode I beschrieben vor einiger Zeit für GRANTs verwenden.

7
user80168

Ich musste den Besitz von Tabellen, Ansichten und Sequenzen ändern und fand, dass die von @rjk gepostete großartige Lösung gut funktioniert - trotz eines Details: Wenn die Objektnamen gemischte Groß- und Kleinschreibung haben (z. B. "TableName"), schlägt dies mit einem " kein Fehler gefunden.
Um dies zu umgehen, schließen Sie die Objektnamen wie folgt mit "" ein:

Tabellen

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;
5
Judge

Basierend auf dem Antwort von elysch ist hier eine Lösung für mehrere Schemata:

DO $$
DECLARE 
  r record;
  i int;
  v_schema text[] := '{public,schema1,schema2,schema3}';
  v_new_owner varchar := 'my_new_owner';
BEGIN
    FOR r IN 
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = ANY (v_schema)
        union all
        select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = ANY (v_schema)
        union all
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = ANY (v_schema)
        union all
        select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = ANY (v_schema)
        union all
        select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner 
    LOOP
        EXECUTE r.a;
    END LOOP;
    FOR i IN array_lower(v_schema,1) .. array_upper(v_schema,1)
    LOOP
        EXECUTE 'ALTER SCHEMA "' || v_schema[i] || '" OWNER TO ' || v_new_owner ;
    END LOOP;
END
$$;
3
JC Boggio

Die Antwort von @Alex Soto ist die richtige und die von @Yoav Aner hochgeladene Gist funktioniert auch, vorausgesetzt, die Tabellen-/Ansichtsnamen enthalten keine Sonderzeichen (die in postgres zulässig sind).

Sie müssen ihnen entkommen, um zu arbeiten, und ich habe ein Gist dafür hochgeladen: https://Gist.github.com/2911117

2
Sharoon Thomas

Das folgende einfachere Shell-Skript hat bei mir funktioniert.

#!/bin/bash
for i in  `psql -U $1  -qt -c  "select tablename from pg_tables where schemaname='$2'"`
do
psql -U $1 -c  "alter table $2.$i set schema $3"
done

Wobei $ 1 - Benutzername (Datenbank) $ 2 = bestehendes Schema $ 3 = neues Schema.

1
sramay

Ich habe ein passendes Skript dafür erstellt. pg_change_db_owner.sh . Dieses Skript ändert den Eigentümer für alle Tabellen, Ansichten, Sequenzen und Funktionen in einem Datenbankschema sowie den Eigentümer des Schemas selbst.

Beachten Sie, dass Sie stattdessen einfach den Befehl REASSIGN OWNED Verwenden können, wenn Sie nur den Besitz aller Objekte in einer bestimmten Datenbank ändern möchten, die einer bestimmten Datenbankrolle gehören.

1
Jakub Jirutka
pg_dump as insert statements 
pg_dump -d -O database filename
-d ( data as inserts ) -O ( capital O is no owner )

Leiten Sie dann die Sicherungsdatei mit folgendem Befehl zurück an PostgreSQL:

psql -d database -U username -h hostname < filename

Da kein Eigentümer angegeben ist, werden alle erstellten Tabellen, Schemas usw. unter dem von Ihnen angegebenen Anmeldebenutzer erstellt.

Ich habe gelesen, dass dies auch ein guter Ansatz für die Migration zwischen PostgreSQL-Versionen sein könnte.

1
atwsKris

Die akzeptierte Lösung kümmert sich nicht um den Funktionsbesitz. Die folgende Lösung kümmert sich um alles.

echo "Database: ${DB_NAME}"
echo "Schema: ${SCHEMA}"
echo "User: ${NEW_OWNER}"

pg_dump -s -c -U postgres ${DB_NAME} | egrep "${SCHEMA}\..*OWNER TO"| sed -e "s/OWNER TO.*;$/OWNER TO ${NEW_OWNER};/" | psql -U postgres -d ${DB_NAME}
# do following as last step to allow recovery
psql -U postgres -d postgres -c "ALTER DATABASE ${DB_NAME} OWNER TO ${NEW_OWNER};"
1
jsh

Ab PostgreSQL 9.0 können Sie GRANT [priv name] ON ALL [object type] IN SCHEMA wo [priv name] ist das typische SELECT, INSERT, UPDATE, DELETE, etc und [object type] kann sein:

  • TABLES
  • SEQUENCES
  • FUNCTIONS

In den PostgreSQL-Dokumenten zu GRANT und REVOKE wird diesbezüglich näher eingegangen. In einigen Situationen ist es immer noch erforderlich, Tricks zu verwenden, die die Systemkataloge betreffen (pg_catalog.pg_*) aber es ist bei weitem nicht so häufig. Ich mache häufig Folgendes:

  1. BEGIN eine Transaktion zum Ändern der Privs
  2. Ändern Sie den Besitz von DATABASES in eine "DBA-Rolle"
  3. Ändern Sie den Besitz von SCHEMAS in die "DBA-Rolle"
  4. REVOKE ALL Privilegien für alle TABLES, SEQUENCES und FUNCTIONS aus allen Rollen
  5. GRANT SELECT, INSERT, UPDATE, DELETE über relevante/passende Tabellen zu den entsprechenden Rollen
  6. COMMIT die DCL-Transaktion.
1
Sean

Entspricht dem @ AlexSoto-Ansatz für Funktionen:

IFS=$'\n'  
for fnc in `psql -qAt -c "SELECT  '\"' || p.proname||'\"' || '(' || pg_catalog.pg_get_function_identity_arguments(p.oid) || ')' FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE n.nspname = 'public';" YOUR_DB` ; do  psql -c "alter function $fnc owner to NEW_OWNER" YOUR_DB; done
1
Anton Smolkov

Docker: Ändern Sie den Eigentümer aller Tabellen + Sequenzen

export user="your_new_owner"
export dbname="your_db_name"

cat <<EOF | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname" | grep ALTER | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname"
SELECT 'ALTER TABLE '||schemaname||'.'||tablename||' OWNER TO $user;' FROM pg_tables WHERE schemaname = 'public';
SELECT 'ALTER SEQUENCE '||relname||' OWNER TO $user;' FROM pg_class WHERE relkind = 'S';
EOF
0
Vojtech Vitek