13

Ich habe eine Datenbank mit Schema public und . Ich muss ein neues Schema schema_b mit der gleichen Struktur als schema_a erstellen. Ich fand die Funktion unten, das Problem ist, dass es die Fremdschlüsseleinschränkungen nicht kopiert.Wie Schemas in PostgreSQL duplizieren

CREATE OR REPLACE FUNCTION clone_schema(source_schema text, dest_schema text) 
    RETURNS void AS 
$BODY$ 
DECLARE 
    object text; 
    buffer text; 
    default_ text; 
    column_ text; 
BEGIN 
    EXECUTE 'CREATE SCHEMA ' || dest_schema ; 

    -- TODO: Find a way to make this sequence's owner is the correct table. 
    FOR object IN 
    SELECT sequence_name::text FROM information_schema.SEQUENCES WHERE sequence_schema = source_schema 
    LOOP 
    EXECUTE 'CREATE SEQUENCE ' || dest_schema || '.' || object; 
    END LOOP; 

    FOR object IN 
    SELECT table_name::text FROM information_schema.TABLES WHERE table_schema = source_schema 
    LOOP 
    buffer := dest_schema || '.' || object; 
    EXECUTE 'CREATE TABLE ' || buffer || ' (LIKE ' || source_schema || '.' || object || ' INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING DEFAULTS)'; 

    FOR column_, default_ IN 
     SELECT column_name::text, REPLACE(column_default::text, source_schema, dest_schema) FROM information_schema.COLUMNS WHERE table_schema = dest_schema AND table_name = object AND column_default LIKE 'nextval(%' || source_schema || '%::regclass)' 
    LOOP 
     EXECUTE 'ALTER TABLE ' || buffer || ' ALTER COLUMN ' || column_ || ' SET DEFAULT ' || default_; 
    END LOOP; 
    END LOOP; 

END; 
$BODY$ LANGUAGE plpgsql 

Wie kann ich klonen/kopieren schema_A mit den Fremdschlüssel-Constraints?

+0

Wenn Sie das Schema mit SQL-Abfrage klonen möchten, lesen Sie [this] (https://stackoverflow.com/questions/2370614/copy-schema-and-create-new-schema-with-different-name- in-der-gleichen-Datenbank/48732283 # 48732283) antwort. – IdanDavidi

Antwort

18

Sie können tun es wahrscheinlich von der Kommandozeile ohne Verwendung von Dateien:

pg_dump -U user --schema='fromschema' database | sed 's/fromschmea/toschema/g' | psql -U user -d database

Hinweis, dass diese Suche und ersetzt alle Vorkommen der Zeichenfolge, die Ihr Schema Name ist, so es beeinflussen können Ihre Daten.

9

würde ich pg_dump das Schema ohne Daten zu speichern:

-s 
--schema-only 

Dump nur die Objektdefinitionen (Schema), keine Daten.

Diese Option ist die Umkehrung von --data-only. Es ist ähnlich, aber aus historischen Gründen nicht identisch mit --section=pre-data --section=post-data.

(Nicht verwechseln mit der --schema Option, die das Wort „Schema“ in einer anderen Bedeutung verwendet.)

Um Tabellendaten nur für eine Teilmenge von Tabellen in der Datenbank ausschließen, siehe --exclude-table-data.

pg_dump $DB -p $PORT -n $SCHEMA -s -f filename.pgsql 

Dann das Schema in der Dump umbenennen (Suche & ersetzen) und es wieder mit psql.

psql $DB -f filename.pgsql 

Fremdschlüssel-Constraints Referenzierung Tabellen in anderen Schema auf das gleiche Schema Punkt kopiert.
Verweise auf Tabellen innerhalb des gleichen Schemas verweisen auf die entsprechenden Tabellen innerhalb des kopierten Schemas.

+0

Ja, danke! aber ich wollte vermeiden, mit Dateien zu arbeiten. Ich suche nach einem schnellen Weg, es zu tun. –

3

Ein bisschen spät zur Party, aber hier einige SQL Sie auf Ihrem Weg helfen könnte:

get Schema oid:

namespace_id = SELECT oid 
        FROM pg_namespace 
       WHERE nspname = '<schema name>'; 

OID get Tabelle:

table_id = SELECT relfilenode 
       FROM pg_class 
       WHERE relnamespace = '<namespace_id>' AND relname = '<table_name>' 

erhalten Fremdschlüssel Einschränkungen:

SELECT con.conname, pg_catalog.pg_get_constraintdef(con.oid) AS condef 
    FROM pg_catalog.pg_constraint AS con 
    JOIN pg_class AS cl ON cl.relnamespace = con.connamespace AND cl.relfilenode = con.conrelid 
WHERE con.conrelid = '<table_relid>'::pg_catalog.oid AND con.contype = 'f'; 

Eine gute Quelle für Tabellen PostgreSQL System kann here finden. Darüber hinaus können Sie mehr über die internen Abfragen lernen, die pg_dump macht, um Dump-Informationen zu sammeln, indem Sie es source code anzeigen.

Wahrscheinlich der einfachste Weg, um zu sehen, wie pg_dump alle Ihre Daten darauf, wie so wäre zu verwenden strace sammelt:

$ strace -f -e sendto -s8192 -o pg_dump.trace pg_dump -s -n <schema> 
$ grep -oP '(SET|SELECT)\s.+(?=\\0)' pg_dump.trace 

Sie werden immer noch durch den Morast der Aussagen sortieren müssen aber, sollte es Helfen Sie dabei, ein Klonwerkzeug programmatisch zusammenzusetzen und vermeiden Sie, dass Sie auf eine Shell fallen müssen, um pg_dump aufzurufen.

+1

Hier ist eine Python-Klasse, die ich gerade geschrieben habe, um einen Schema-Klon (einschließlich Datenkopie) unter Verwendung von SQL und ohne Shelling nach pg_dump zu erstellen: [https://gist.github.com/rabbitt/97f2c048d9e38c16ce62](https://gist .github.com/rabatt/97f2c048d9e38c16ce62) – rabbitt