能否从pg_dumpall中导入一个数据库?

10

我想从pg_dumpall中获取一个指定名称的数据库,并将其导入到我的本地postgres。如果可能,我希望在我的本地机器上使用不同的数据库名称。是否可行?


您需要创建一个新的临时PostgreSQL实例,进行initdb初始化操作,然后将pg_dumpall输出还原到该实例上,并仅使用pg_dump -Fc命令备份所需的数据库以便于后续pg_restore操作。 - Craig Ringer
3个回答

21
似乎PostgreSQL没有内置的方法来做到这一点,因此我编写了一个脚本来处理这个问题。以下是我的学习心得,在gist中有更多注释,但简而言之: pg_dumpall包含多个SQL导入语句,每个语句对应服务器上的一个数据库。
您可以通过搜索这两个字符串轻松找到每个数据库的开头和结尾: \connect databasenamePostgreSQL database dump complete 这两个字符串之间的内容组成了每个导入的内容。我省略了我创建的导出文件的第一行。在脚本顶部使用\connect databasename意味着该数据库必须已经存在。因此,如果您想将数据库导入到不同的名称下,可以安全地删除第一行,并像这样运行导入命令: psql new_databasename < databasename.sql 这需要很长时间才能在大型数据库上运行,所以如果需要,我可能会稍后重构它以加快速度,但目前它可以正常工作。它还会输出一个postgres.sql导出文件,我还没有测试过导入该文件,但是如果您只想从pg_dumpall中提取一个数据库,那么这个脚本就可以胜任。

https://gist.github.com/brock/63830f11c0945f82f9ea

将此gist中的文件保存到您的~/bin中,命名为pg_extract,并使其可执行。您可以通过传递原始sql dump文件的文件名来运行它:pg_extract postgresql_dump.sql。您将在当前目录中找到每个数据库的.sql文件。

编辑:我现在已经更新了脚本,以便您可以传递要提取的数据库名称,并在那里停止。例如:pg_extract postgresql_dump.sql databasename会输出一个单独的databasename.sql文件。


非常感谢,这帮了我大忙。 - user1803784
很高兴听到它仍然对你有用 @user1803784 - brock

10
这个小脚本可以实现这个功能。
    #!/bin/bash

    [ $# -lt 2 ] && { echo "Usage: $0 <postgresql dump> <dbname>"; exit 1; }

    sed  "/connect.*$2/,\$!d" $1 | sed "/PostgreSQL database dump complete/,\$d"

(它会将内容写入标准输出,你需要将其导入到一个文件中。)

这是一些非常巧妙的 sed 使用。谢谢! - workflow
稍作修改,以确保匹配 "\connect<空格><数据库名>" sed --regexp-extended "/\\\\connect\\s+$1/,\$!d" "$2" | sed "/PostgreSQL database dump complete/,\$d" - KeKru

0
不,您需要从转储中提取相关部分。使用pg_dump --format=custom可以在还原方面提供更多的灵活性,但我认为使用该方法无法将其还原到不同的数据库中。
编辑:实际上,您可以使用pg_restore --dbname=foo来实现。

如果你只有一个ASCII转储文件,可以使用一个好的文本编辑器来剪切出你想要恢复的部分。你可能需要使用一个既不受行长度限制,也不受文件大小限制,也不会对UTF-8感到困惑的编辑器。 - Jasen
这就是我说的,他需要从转储中提取相关端口。 - Andy Gajetzki
1
不起作用。pg_restore:[归档程序] 输入文件似乎是文本格式的转储。请使用psql。 - Simon Woodside

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接