我想使用不同的架构还原数据库

时间:2010-11-16 06:20:18

标签: postgresql pg-dump pg-restore

我使用以下命令

转储了名为temp1的数据库
$  pg_dump -i -h localhost  -U postgres -F c -b -v -f pub.backup temp1 

现在我想在另一个名为“db_temp”的数据库中恢复转储,但是我只想在“temp_schema”中创建所有表(而不是fms temp1数据库中的默认模式)它位于“db_temp”数据库​​中。

有没有办法使用pg_restore命令执行此操作?

任何其他方法也值得赞赏!

8 个答案:

答案 0 :(得分:56)

有一个简单的解决方案:

  • 以纯SQL格式创建备份转储(格式" p"使用参数--format=p-F p
  • 使用您喜欢的编辑器编辑pub.backup.sql转储,并在文件顶部添加以下两行:
  

create schema myschema;

     

SET search_path TO myschema;

现在您可以使用命令

恢复备份转储
  

psql -f pub.backup.sql

set search_path to <schema>命令将myschema设置为默认值,以便在此模式中创建新表和其他对象,而不依赖于&#34;默认值&#34;他们之前住过的架构。

答案 1 :(得分:44)

快速而肮脏的方式:

1)重命名默认架构:

alter schema public rename to public_save;

2)创建新架构作为默认架构:

create schema public;

3)恢复数据

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

4)根据需要重命名模式:

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

答案 2 :(得分:10)

可能最简单的方法是在恢复后简单地重命名模式,即使用以下SQL:

ALTER SCHEMA my_schema RENAME TO temp_schema

我相信因为您使用压缩归档格式输出pg_dump,所以在恢复之前无法改变它。选项是使用默认输出并对模式名称进行搜索和替换,但这样做会有风险,如果不小心可能会导致数据损坏。

答案 3 :(得分:10)

pg_restore本身没办法。你可以做的是使用pg_restore生成SQL输出,然后通过例如sed脚本发送它来更改它。您需要注意如何编写该sed脚本,因此它不匹配并更改数据中的内容。

答案 4 :(得分:3)

如果您只有几张桌子,那么您可以一次恢复一张桌子,pg_restore在您指定-d database时接受-t tablename。当然,您必须在恢复表之前设置模式,然后在完成恢复表时对索引和约束进行排序。

或者,在另一个端口上设置另一台服务器,使用新的PostgreSQL服务器进行还原,重命名架构,转储它,然后还原到原始数据库。这当然是一个很好的障碍,但它将完成工作。

如果您有冒险精神,可以使用十六进制编辑器更改转储文件中的数据库名称。我认为它只在转储中的一个地方被提及,只要新旧数据库名称相同它应该工作。 YMMV,在生产环境中不要做这样的事情,如果爆炸并且平衡你的家乡以及所有其他通常的免责声明,不要怪我。

答案 5 :(得分:2)

在临时数据库中重命名架构。

导出架构:

pg_dump --schema-only --schema=prod > prod.sql

创建一个新数据库。恢复导出:

psql -f prod.sql

ALTER SCHEMA prod RENAME TO somethingelse;

pg_dump --schema-only --schema=somethingelse > somethingelse.sql

(删除数据库)

对于数据,您只需修改顶部的search_path集。

答案 6 :(得分:1)

如上所述,在转储/恢复过程中,pg_dump,psql或pg_restore没有直接支持来更改模式名称。但是使用“普通”格式导出然后修改.sql文件相当简单。这个Bash脚本做了基础:

rename_schema () {

  # Change search path so by default everything will go into the specified schema
  perl -pi -e "s/SET search_path = $2, pg_catalog/SET search_path = $3, pg_catalog, $2;/" "$1"

  # Change 'ALTER FUNCTION foo.' to 'ALTER FUNCTION bar.'
  perl -pi -e 's/^([A-Z]+ [A-Z]+) '$2'\./$1 '$3'./' "$1"

  # Change the final GRANT ALL ON SCHEMA foo TO PUBLIC
  perl -pi -e 's/SCHEMA '$2'/SCHEMA '$3'/' "$1"

}

用法:

pg_dump --format plain --schema=foo --file dump.sql MYDB
rename_schema dump.sql foo bar
psql -d MYDB -c 'CREATE SCHEMA bar;'
psql -d MYDB -f dumpsql

答案 7 :(得分:0)

这个问题很老了,但也许可以帮助一些人。

pg_restore 的输出流式传输到 sed 并替换架构名称,以便将转储导入不同的架构。

类似于:

pg_restore ${dumpfile} | \
    sed -e "s/OWNER TO ${source_owner}/OWNER TO ${target_owner}/" \
        -e "s/${source_owner}/${target_schema}/" | \
       psql -h ${pgserver} -d ${dbname} -U ${pguser}