有没有办法导出 PostgreSQL 数据库然后用另一个名称导入它?
我在 Rails 中使用 PostgreSQL,我经常从生产环境导出数据,其中数据库名为 blah_production,然后将其导入开发环境或暂存环境,名称为 blah_development 和 blah_staging。在 MySQL 上这很简单,因为导出时没有任何地方有数据库(可能除了注释),但在 PostgreSQL 上这似乎是不可能的。难道不可能吗?
我目前正在通过以下方式转储数据库:
pg_dump blah > blah.dump
我没有使用 -c 或 -C 选项。该转储包含如下语句:
COMMENT ON DATABASE blah IS 'blah';
ALTER TABLE public.checks OWNER TO blah;
ALTER TABLE public.users OWNER TO blah;
当我尝试导入时
psql blah_devel < blah.dump
我明白了
WARNING: database "blah" does not exist
ERROR: role "blah" does not exist
也许问题实际上不是出在数据库而是出在角色上?
如果我以这种方式转储它:
pg_dump --format=c blah > blah.dump
并尝试通过以下方式导入:
pg_restore -d blah_devel < tmp/blah.psql
我收到这些错误:
pg_restore: WARNING: database "blah" does not exist
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 1513; 1259 16435 TABLE checks blah
pg_restore: [archiver (db)] could not execute query: ERROR: role "blah" does not exist
Command was: ALTER TABLE public.checks OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1509; 1259 16409 TABLE users blah
pg_restore: [archiver (db)] could not execute query: ERROR: role "blah" does not exist
Command was: ALTER TABLE public.users OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1508; 1259 16407 SEQUENCE users_id_seq blah
pg_restore: [archiver (db)] could not execute query: ERROR: role "blah" does not exist
Command was: ALTER TABLE public.users_id_seq OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1824; 0 0 ACL public postgres
pg_restore: [archiver (db)] could not execute query: ERROR: role "postgres" does not exist
Command was: REVOKE ALL ON SCHEMA public FROM postgres;
pg_restore: [archiver (db)] could not execute query: ERROR: role "postgres" does not exist
Command was: GRANT ALL ON SCHEMA public TO postgres;
WARNING: errors ignored on restore: 11
有任何想法吗?
我看到有人使用 sed 脚本来修改转储。我想避免使用这种解决方案,但如果没有其他选择,我会采用它。有人写过脚本来更改转储的数据库名称以确保不会更改任何数据吗?
答案1
解决方案是像这样转储它:
pg_dump --no-owner --no-acl blah > blah.psql
并像这样导入它:
psql blah_devel < blah.psql > /dev/null
我仍然收到此警告:
WARNING: database "blah" does not exist
但其余部分似乎有效。
答案2
如果您正在创建文本转储,则可以导出不带位的数据库CREATE DATABASE
(即不指定-c
和-C
选项pg_dump
);这将阻止Postgres尝试删除,创建和连接数据库。
如果您使用其中一种存档格式,您可以指定要还原到的数据库的名称-d
选项。pg_restore
查看手册页了解pg_dump
更多pg_restore
详细信息,并且不要忘记安装抓猴子在您在生产系统上尝试此操作之前,我可能会遗漏一些重要细节。
答案3
现在 pg_restore 有 -d 选项,您可以设置用于导入数据的数据库名称。
在源头上:
pg_dump -v -Fc mydb.dmp mydb
在目的地:
createdb -T template1 mydb2
pg_restore -v -e -d mydb2 mydb.dmp