I want to restore the database with a different schema

74,348

Solution 1

There's no way in pg_restore itself. What you can do is use pg_restore to generate SQL output, and then send this through for example a sed script to change it. You need to be careful about how you write that sed script though, so it doesn't match and change things inside your data.

Solution 2

A quick and dirty way:

1) rename default schema:

alter schema public rename to public_save;

2) create new schema as default schema:

create schema public;

3) restore data

pg_restore -f pub.backup db_temp [and whatever other options]

4) rename schemas according to need:

alter schema public rename to temp_schema;
alter schema public_save rename to public;

Solution 3

There is a simple solution:

  • Create your backup dump in plain SQL format (format "p" using the parameter --format=p or -F p)
  • Edit your pub.backup.sql dump with your favorite editor and add the following two lines at the top of your file:

create schema myschema;

SET search_path TO myschema;

Now you can restore your backup dump with the command

psql -f pub.backup.sql

The set search_path to <schema> command will set myschema as the default, so that new tables and other objects are created in this schema, independently of the "default" schema where they lived before.

Solution 4

Probably the easiest method would be to simply rename the schema after restore, ie with the following SQL:

ALTER SCHEMA my_schema RENAME TO temp_schema

I believe that because you're using the compressed archive format for the output of pg_dump you can't alter it before restoring. The option would be to use the default output and do a search and replace on the schema name, but that would be risky and could perhaps cause data to be corrupted if you were not careful.

Solution 5

If you only have a few tables then you can restore one table at a time, pg_restore accepts -d database when you specify -t tablename. Of course, you'll have to set up the schema before restoring the tables and then sort out the indexes and constraints when you're done restoring the tables.

Alternatively, set up another server on a different port, restore using the new PostgreSQL server, rename the schema, dump it, and restore into your original database. This is a bit of a kludge of course but it will get the job done.

If you're adventurous you might be able to change the database name in the dump file using a hex editor. I think it is only mentioned in one place in the dump and as long as the new and old database names are the same it should work. YMMV, don't do anything like this in a production environment, don't blame me if this blows up and levels your home town, and all the rest of the usual disclaimers.

Share:
74,348
abubacker
Author by

abubacker

I am a senior software programmer

Updated on July 05, 2022

Comments

  • abubacker
    abubacker almost 2 years

    I have taken a dump of a database named temp1, by using the follwing command

    $  pg_dump -i -h localhost  -U postgres -F c -b -v -f pub.backup temp1 
    

    Now I want to restore the dump in a different database called "db_temp" , but in that I just want that all the tables should be created in a "temp_schema" ( not the default schema which is in the fms temp1 database ) which is in the "db_temp" database.

    Is there any way to do this using pg_restore command?

    Any other method also be appreciated!

  • abubacker
    abubacker over 13 years
    This solution can make a lot of mess isn't it
  • Hamish
    Hamish over 13 years
    In what way?? The SQL statement is the only safe way to change a schema name. The other solution is also suggested in another answer and we both explain that it's risky. Poor downvoting.
  • Andrea Girardi
    Andrea Girardi over 12 years
    I changed the schema name but, after that, I'm not able to change the serach path! User is not able to search any table after the rename!
  • Peter Ehrlich
    Peter Ehrlich about 9 years
    Is there a neat way to actually edit only the head of a large dump file? Even things like this involve duplicating it: superuser.com/questions/246837/…
  • David
    David about 9 years
    @PeterEhrlich Depending on how large your files are and available RAM, you can use vim to open a gzip'd dump file directly. It still gets expanded in memory but I was able to open, edit, and save a 750MB (.gz) file with only a short pause when saving. YMMV.
  • David
    David about 9 years
    I found my dumps already had one or more SET search_path TO ...; lines that I needed to remove. You may want to search for "search_path" when editing and before restoring.You'll have at least one SET search_path TO ...; line for each schema from which objects were dumped. It would be nice if there were a --without-schema option that worked like the --no-owner option.
  • Suhas
    Suhas about 8 years
    @PeterEhrlich You can use a subprocess to write something to a file before the contents of the dump. For example: ( echo "CREATE SCHEMA myschema; SET search_path TO myschema;" ; pg_dump -F p ... ) | gzip -9 > dump.sql.gz
  • J-DawG
    J-DawG about 7 years
    @PeterEhrlich - I find it easiest to use sed: sed -i s/SET search_path TO old_schema/SET search_path TO new_schema/ mydumpfilepath
  • Andy Smith
    Andy Smith almost 7 years
    @gldnspud but as I understand it this will just mean there's 2 "SET search_path"s in the file? The second one being the one we don't want.
  • Admin
    Admin about 6 years
    This won't work in Postgres 9.6.8 / 10.3: pg_dump no longer uses SET search_path; instead, it prefixes the schema name to all commands in the dump
  • Steve Bennett
    Steve Bennett almost 6 years
    (Everyone: Please feel free to update this answer to improve the Bash.)
  • Pipo
    Pipo about 5 years
    I would have done it with sed "s/\b$OLD_SCHEMA/$NEW_SCHEMA/g"
  • Ameba Brain
    Ameba Brain almost 4 years
    and what to do in case of large project with up to 300 tables? also single non-compressed sql file? you will also loose parallel feature during restore
  • John Smith
    John Smith almost 3 years
    you meant pg_dump as the first command opposed to pg_restore?
  • Dwhitz
    Dwhitz almost 3 years
    @JohnSmith no I mean pg_restore. You should do your dump and then perform the replace schema while importing the dump on the target db.
  • Sakari Cajanus
    Sakari Cajanus over 2 years
    As mentioned in one of the other answers, one needs to be careful if the schema name exists elsewhere (e.g. in the data). His perl script is slightly safer than plain substituting all appearances of $OLD_SCHEMA.
  • snackbar
    snackbar about 2 years
    @Dwhitz there's small typo error; it should be {"source_schema"/"target_schema"/}
  • agoldev
    agoldev almost 2 years
    I know the answer is old, but for someone that just wants to use this accepted answer: @shaunc is way more secure and robust, and works with compressed dumps.