我有一个名为 units
的表,它存在于同一数据库中的两个单独的架构中(我们将其称为 old_schema
和 new_schema
>)。两种模式中的表结构是相同的。唯一的区别是 new_schema
中的 units
表目前为空。
我正在尝试从 old_schema
中的表中导出数据,并将其导入到 new_schema
中。我使用 pg_dump 来处理导出,如下所示:
pg_dump -U username -p 5432 my_database -t old_schema.units -a > units.sql
然后我尝试使用以下命令导入它:
psql -U username -p 5432 my_database -f units.sql
不幸的是,这似乎尝试重新插入到old_schema
中。查看生成的sql文件,似乎有一行,我认为是导致此问题的原因:
SET search_path = mysql_migration, pg_catalog;
事实上,我可以更改此行以读取
SET search_path = public;
事实证明这确实是成功的,但我不认为这是实现这一目标的“正确”方法。
问题:通过 pg_dump 生成的脚本导入数据时,如何指定数据应进入哪个模式而不更改生成的文件?
最佳答案
根据您描述的场景,这里有两个主要问题。
- 您提到的架构差异。
- 事实上,通过 pg_dump 转储整个表,您也会转储表定义,如果该表已存在于目标架构中,这将导致问题。
要仅转储数据,如果目标数据库中已存在该表(根据上述情况似乎属于这种情况),您可以使用带有 --data-only
标志的 pg_dump 转储该表.
然后,为了解决架构问题,我建议对输出 sql 文件进行搜索/替换(sed 是一种快速的方法),将 old_schema
替换为 new_schema
。
这样,它将把数据(这是文件中的所有内容,而不是表定义本身)应用到 new_schema
中的表。
如果您需要更广泛的解决方案来支持动态命名模式,您可以使用与 sed 相同的搜索/替换技巧,但不要将其替换为 new_schema
,而是将其替换带有一些占位符文本,例如 $$placeholder_schema$$
(极不可能在文件中的其他地方作为标记出现的东西),然后,当您需要将该文件应用于特定模式时,使用原始文件作为模板,复制它,然后然后使用 sed 或类似工具修改副本,将占位符标记替换为所需的即时架构名称。
您可以在命令行上为psql设置一些选项,例如 --set AUTOCOMMIT=off
,但是,使用 SEARCH_PATH
的类似方法似乎没有任何效果。
相反,它需要形式 \set SEARCH_PATH to <path>
,可以使用 -c
选项指定,但不能与 -f
组合(它是 or )。
鉴于此,我认为在这种情况下使用 sed 修改文件可能是与 -f
一起使用的最佳选择。
关于sql - 使用 pg_dump 从一个模式导出并导入到另一个模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24921596/