5

我正在foo_tabledatabase_a 中创建一个外部表 ( )。foo_table住在 database_b 中。 foo_table有一个枚举 ( bar_type) 作为其列之一。因为此枚举在 database_b 中,所以在 database_a 中创建外部表失败。database_a 不理解列类型。在 database_a 中运行以下命令

CREATE FOREIGN TABLE foo_table (id integer NOT NULL, bar bar_type) SERVER database_b

一个得到错误:

ERROR: type "bar_type" does not exist

我可以bar_type在 database_a 中创建一个副本,但这感觉是重复的,并且可能是未来不一致的原因。有人会对处理的最佳实践有想法吗?

4

3 回答 3

8

我总结了我从 pgsql-general 邮件列表中收到的答案:

  1. 外部表基本上是本地数据库的临时远程数据源,因此本地数据库有责任维护其对远程表的定义,无论它是在另一个(甚至是相同的)PostgreSQL服务器还是完全不同的数据源,尤其是本地定义可能与远程定义不同。
  2. 这确实意味着没有简单的方法可以确保本地服务器上存在任何远程依赖项。PostgreSQL 9.5 将提供 IMPORT FOREIGN SCHEMA 命令,但这仅限于表/视图定义。
  3. 如果枚举的定义变得不一致,我们预计在检索具有本地未知值的行时会发生错误。
  4. 一种可能的解决方法是将外部表的列声明为“文本”而不​​是枚举;您将在本地丢失一些错误检查,但远程服务器将在您存储某些内容时强制执行有效性。
  5. 但是,不清楚这种 hack 是否会在枚举列上的 WHERE 条件下表现得令人满意。我将检查 WHERE 条件的性能,并在我有更多详细信息时更新此答案。

所有功劳都归于 pgsql-general 邮件列表中的优秀人员。

于 2015-05-28T18:28:54.913 回答
0

在真正的紧要关头(当您没有太多枚举/域时)。它可以在运行导入之前在新的本地外部模式中手动创建每个模式。

就我而言,我正在使用postgres_fdw数据库之间罕见的大容量迁移,这些迁移受益于纯粹在 SQL 中运行,而不是通过某处的应用程序服务器。

由于我们只是偶尔这样做,并且 Postgres 枚举的编号是 10 秒,而不是 100 秒,因此这种解决方法可以保持在 Postgres 服务器上运行迁移的性能优势。

于 2021-07-19T05:44:57.100 回答
0

您可以通过进行此查询来创建一个脚本来传输枚举,然后在您的服务器上创建它们:

SELECT format(
          'CREATE TYPE %s AS ENUM (%s);',
          enumtypid::regtype,
          string_agg(quote_literal(enumlabel), ', ')
       )
FROM pg_enum
GROUP BY enumtypid;

感谢@laurenz-albe Postgres 如何从外部服务器传输所有枚举

于 2021-10-15T12:05:53.357 回答