2017-03-02 1 views
0

Ich habe eine Mult-Tenant-Anwendung, in der Mandanten in verschiedenen Schemas innerhalb derselben Datenbank eingerichtet werden. Der Grund dafür ist, dass sie einige gemeinsame Daten haben, die sie für eines der Schemata verwenden.Postgres run-Anweisung für mehrere Schemas

Bis jetzt habe ich ein Bash-Skript mit einer Liste der darin enthaltenen Schemata verwendet, die jedes Mal aktualisiert werden muss, wenn ein neues Schema hinzugefügt wird, und ich muss Änderungen an Tabellenschemas über die Konten vornehmen. Zum Beispiel eine neue Spalte zu einer Tabelle hinzufügen.

Gibt es eine Möglichkeit in Postgres, psql, etc ... zum Beispiel auszuführen

ALTER TABLE some_table ADD COLUMN some_column TEXT NOT NULL DEFAULT ''; 

ohne String Ersatz in einem anderen Skript wie bash zum Beispiel zu tun.

Also mit anderen Worten gibt es einen einfachen Weg, um die Schemas zu bekommen, und in psql eine for-Schleife schreiben, die durch die Schemata iterieren und die Anweisung jeweils durch Setzen von search_path zum Beispiel ausführen.

Der Grund dafür ist, dass die Anzahl der Mandanten wächst und neue Benutzer von Administratoren hinzugefügt werden können, die keine Entwickler sind. Daher aktualisiere ich ständig meine Shell-Skripte. Dies wird nur exponentiell wachsen. Gibt es eine Standardmethode, um diese Art von Problem zu lösen?

+0

Ja, können Sie eine Prozedur auf das Hauptschema (Posgres) zu erstellen hole alle Schemas wie im Schema INFORMATION_SCHEMA und machen Sie Ihre Änderung den Befehl für sie ausführen –

Antwort

3

Sie können mit einem kleinen PL/pgSQL Block tun:

do 
$$ 
declare 
    s_rec record; 
begin 
    for s_rec in select schema_name 
       from information_schema.schemata 
       where schema_name not in ('pg_catalog', 'information_schema') 
    loop 
    execute format ('ALTER TABLE if exists %I.some_table ADD COLUMN some_column TEXT NOT NULL DEFAULT ''''), s_rec.schema_name); 
    end loop; 
end; 
$$ 

Die if exists die Aussage sicher nicht scheitern lassen, wenn die Tabelle im Schema nicht vorhanden ist.


Wenn Sie Ihre Frage zu stark vereinfachte und wollen in der Tat für jedes Schema komplette Skripte einmal ausführen, ein Skript für jedes Schema zu erzeugen, die das eigentliche Skript enthält wahrscheinlich ist einfacher:

select concat(format('set search_path = %I;', schema_name), 
       chr(10), 
       '\i complete_migration_script.sql') 
from information_schema.schemata 
where schema_name not in ('pg_catalog', 'information_schema') 

können Sie spool die Ausgabe dieser Anweisung in eine Datei und dann diese Datei mit psql (natürlich müssen Sie complete_migration_script.sql durch den tatsächlichen Namen des Skripts ersetzen)

+0

Erstaunlich, ich brauche eigentlich beide Fälle, die Sie Beispiele zur Verfügung gestellt haben. Vielen Dank!!! –

Verwandte Themen