Duplicate postgresql schema including sequences

后端 未结 3 397
清歌不尽
清歌不尽 2021-01-02 18:49

My database layout needs to create new schema for each new customer. Currently I use internal function I found on the net and modified a little bit.

CREATE F         


        
3条回答
  •  离开以前
    2021-01-02 19:13

    The root of the problem

    The connection to the old sequence comes from a plain default value for the involved column. I quote the manual here:

    Default expressions for the copied column definitions will only be copied if INCLUDING DEFAULTS is specified. The default behavior is to exclude default expressions, resulting in the copied columns in the new table having null default.

    Since you create new tables with

    INCLUDING ALL
    

    And:

    INCLUDING ALL is an abbreviated form of INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS.

    .. you get the same default. You can either exclude defaults or explicitly change default values including nextval() for the new tables after you created them. I don't think there is any middle ground.


    Simpler with dump / hack the dump / restore

    or even another reliable way to duplicate entire schema

    You could dump the schema of schema (same word, different meaning) with pg_dump:

    pg_dump $DB -p $PORT -n $SCHEMA -sf /var/lib/postgresql/your_name.pgsql
    

    Hack the dump (meaning: use a text editor on it, or script it): exchange the schema name at the top of the dump, and all other occurrences in SET search_path and as schema-qualification for sequences and possibly more. If you chose a unique name for the schema, a single run of global search & replace with your favorite tool (sed or vim or ...) should do the job.

    Then run the SQL script with psql against the same or any other database:

    psql $DB -p $PORT -f /var/lib/postgresql/your_name.pgsql > /dev/null
    

    Contrary to what I first posted, serial columns are still split up in the dump (at least in PostgreSQL 9.1.5). The SQL script creates sequences separately, attaches them to the serial column with:

    ALTER SEQUENCE seq OWNED BY tbl.col;
    

    and sets the default value separately.

    As an aside: Current versions of pgAdmin reverse engineer serial columns in DDL scripts when all the requirements are met.

提交回复
热议问题