SQL:创建具有枚举列的外部 table 时出错
SQL: error when creating a foreign table that has an enum column
我正在 database_a 中创建一个外国 table (foo_table
)。 foo_table
住在 database_b。 foo_table
有一个枚举 (bar_type
) 作为其列之一。因为此枚举在 database_b 中,所以在 database_a 中创建外部 table 失败。 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
我可以在 database_a 中创建一个 bar_type
的副本,但这感觉是重复的,并且可能是未来不一致的原因。有人对处理的最佳做法有想法吗?
我总结了我从 pgsql-general 邮件列表收到的答案:
- 外部 table 基本上是本地数据库的临时远程数据源,因此本地数据库有责任维护其对远程 table 的定义,无论它是否在另一个(甚至相同的)PostgreSQL 服务器或完全不同的数据源,尤其是本地定义可能与远程定义不同。
- 这确实意味着没有简单的方法可以确保本地服务器上存在任何远程依赖项。 PostgreSQL 9.5 将提供 IMPORT FOREIGN SCHEMA 命令,但这仅限于 table/view 个定义。
- 如果枚举的定义变得不一致,我们预计在检索具有本地未知值的行时会发生错误。
- 一个可能的解决方法是将外部 table 的列声明为 "text" 而不是枚举;你会在本地丢失一些错误检查,但远程服务器会在你执行时强制执行有效性
存储了一些东西。
- 但是,尚不清楚此 hack 是否会在枚举列上的 WHERE 条件下正常运行。我将检查 WHERE 条件的性能,并在我有更多详细信息时更新此答案。
所有功劳归功于 pgsql-general 邮件列表中的优秀人员。
在真正的紧要关头(当你没有太多的时候 enums/domains)。它可以在 运行 导入之前在新的本地外部模式中手动创建每一个。
在我的例子中,我使用 postgres_fdw
在数据库之间进行罕见的大量迁移,这些数据库完全受益于 运行 SQL,而不是通过某个地方的应用程序服务器。
由于我们只是偶尔这样做,并且 Postgres 枚举编号为 10 位,而不是 100 位,因此此解决方法是可行的,可以保持 运行 Postgres 服务器上的迁移的性能优势。
您可以创建一个脚本来通过进行此查询来传输枚举,然后在您的服务器上创建它们:
SELECT format(
'CREATE TYPE %s AS ENUM (%s);',
enumtypid::regtype,
string_agg(quote_literal(enumlabel), ', ')
)
FROM pg_enum
GROUP BY enumtypid;
谢谢@laurenz-albe
我正在 database_a 中创建一个外国 table (foo_table
)。 foo_table
住在 database_b。 foo_table
有一个枚举 (bar_type
) 作为其列之一。因为此枚举在 database_b 中,所以在 database_a 中创建外部 table 失败。 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
我可以在 database_a 中创建一个 bar_type
的副本,但这感觉是重复的,并且可能是未来不一致的原因。有人对处理的最佳做法有想法吗?
我总结了我从 pgsql-general 邮件列表收到的答案:
- 外部 table 基本上是本地数据库的临时远程数据源,因此本地数据库有责任维护其对远程 table 的定义,无论它是否在另一个(甚至相同的)PostgreSQL 服务器或完全不同的数据源,尤其是本地定义可能与远程定义不同。
- 这确实意味着没有简单的方法可以确保本地服务器上存在任何远程依赖项。 PostgreSQL 9.5 将提供 IMPORT FOREIGN SCHEMA 命令,但这仅限于 table/view 个定义。
- 如果枚举的定义变得不一致,我们预计在检索具有本地未知值的行时会发生错误。
- 一个可能的解决方法是将外部 table 的列声明为 "text" 而不是枚举;你会在本地丢失一些错误检查,但远程服务器会在你执行时强制执行有效性 存储了一些东西。
- 但是,尚不清楚此 hack 是否会在枚举列上的 WHERE 条件下正常运行。我将检查 WHERE 条件的性能,并在我有更多详细信息时更新此答案。
所有功劳归功于 pgsql-general 邮件列表中的优秀人员。
在真正的紧要关头(当你没有太多的时候 enums/domains)。它可以在 运行 导入之前在新的本地外部模式中手动创建每一个。
在我的例子中,我使用 postgres_fdw
在数据库之间进行罕见的大量迁移,这些数据库完全受益于 运行 SQL,而不是通过某个地方的应用程序服务器。
由于我们只是偶尔这样做,并且 Postgres 枚举编号为 10 位,而不是 100 位,因此此解决方法是可行的,可以保持 运行 Postgres 服务器上的迁移的性能优势。
您可以创建一个脚本来通过进行此查询来传输枚举,然后在您的服务器上创建它们:
SELECT format(
'CREATE TYPE %s AS ENUM (%s);',
enumtypid::regtype,
string_agg(quote_literal(enumlabel), ', ')
)
FROM pg_enum
GROUP BY enumtypid;
谢谢@laurenz-albe