postgresql 必须先提交新枚举值,然后才能使用它们

f5emj3cl  于 2023-03-01  发布在  PostgreSQL
关注(0)|答案(3)|浏览(155)

我正在将PostgreSQL从9.6升级到13。以下脚本适用于9.6:

BEGIN

CREATE TYPE x AS ENUM ('foo', 'bar');
ALTER TYPE x ADD VALUE 'baz';
SELECT 'baz'::x;

END;

但在13号的结尾是:

ERROR:  unsafe use of new value "baz" of enum type x
LINE 1: SELECT 'baz'::x;
               ^
HINT:  New enum values must be committed before they can be used.

谷歌搜索显示这是早于13,但我不知 prop 体是哪个版本。
我确信我有一个很好的理由在同一个事务中创建枚举,添加值并使用这个值。
是否有任何已知的干净变通方案?

[编辑] -我为什么要这么做

我有一组SQL文件

v_0.01.sql
v_0.02.sql
v_0.03.sql
...

是增量的,即“数据库版本X”包含在“X之前的所有SQL文件”中,例如版本0.02随一起安装

cat v_0.01.sql v_0.02.sql | psql -1

其中一些文件包含CREATE TYPE,另一些包含ALTER TYPE。我可能会在以后的文件中添加更多这样的文件。
这很方便,因为在任何给定时刻,我都可以很容易地:

  • 安装任何所需版本全新数据库
  • 将数据库从任何版本升级到任何其它版本
  • 检查版本之间的差异

在9.6上,第二个点需要更多的工作-即在事务之外执行任何ALTER TYPE。在13上,第一个操作也需要这样做,这很不方便,因为我经常这样做,而且有更多的total-SQL,所以有更多的ALTER TYPE
我想保留:

  • 现行文件结构
  • 轻松安装全新数据库
  • 单事务安装(psql -1)-这样我就不会把正确的安装与失败的安装混淆起来
dwthyt8l

dwthyt8l1#

Postgres 9.6文档已在此状态
ALTER TYPE ... ADD VALUE(向枚举类型添加新值的形式)不能在事务块内执行。
在同一事务中创建枚举时,似乎存在未记录的此规则异常。这不应该起作用。
从Postgres 12开始,现在支持在事务期间添加新值,但不支持在相同的:

  • 允许更灵活地添加枚举值(Andrew Dunstan、Tom Lane、Thomas Munro)

以前,不能在事务块中调用ALTER TYPE ... ADD VALUE,除非它是创建枚举类型的同一事务的一部分。现在,只要在提交新枚举值之前不引用它,就可以在以后的事务中调用它。
Postgres 12.0 release notes
看来这条规则的修改弥补了你所利用的漏洞。
至于变通方法,您可能希望使用临时表来存储枚举,并仅在事务的最后创建它们的类型。看看Adding a new value to an existing ENUM Type(它记录了ADD VALUE之前的解决方案)以获得灵感。

wooyq4lh

wooyq4lh2#

只需在ALTER TYPE行后添加COMMIT;即可提交数据库中的更改。

CREATE TYPE x AS ENUM ('foo', 'bar');
ALTER TYPE x ADD VALUE 'baz';
COMMIT;
SELECT 'baz'::x;

如果使用flyway时遇到这个问题-将alter和select语句拆分到不同的文件。

42fyovps

42fyovps3#

ALTER TYPE对我起作用之后添加COMMIT;

ALTER TYPE type_name ADD VALUE value; 
COMMIT;

相关问题