迁移到 PostgreSQL 上的标识列,但没有修改 pg_depend 的权限

问题描述 投票:0回答:1

在准备发布 Doctrine DBAL 4 时,我想将基于自动增量的表的标识列迁移到“串行”类型列,如下所述:

迁移到 PostgreSQL 上的标识列

包含一个很好的脚本和一切。

问题是这个脚本运行这个:

-- change the dependency between column and sequence to internal
  UPDATE pg_depend
    SET deptype = 'i'
    WHERE (classid, objid, objsubid) = ('pg_class'::regclass, seqid, 0)
      AND deptype = 'a';

由于我的数据库作为托管数据库托管在 DigitalOcean 上,因此我的

doadmin
用户没有足够的权限直接修改此表:

ERROR:  permission denied for table pg_depend
CONTEXT:  SQL statement "UPDATE pg_depend
   SET deptype = 'i'
   WHERE (classid, objid, objsubid) = ('pg_class'::regclass, seqid, 0)
     AND deptype = 'a'"
PL/pgSQL function upgrade_serial_to_identity(regclass,name) line 31 at SQL statement

如何在无权更改此用户的权限或此表权限的情况下执行此迁移?

postgresql doctrine dbal
1个回答
0
投票

像这样修改目录表是危险的,并且可能会导致数据损坏。如果有一种快速简单的方法来做到这一点,为什么这么复杂?

给定一个这样的表:

\d s
                            Table "laurenz.s"
 Column │  Type   │ Collation │ Nullable │            Default            
════════╪═════════╪═══════════╪══════════╪═══════════════════════════════
 id     │ integer │           │ not null │ nextval('s_id_seq'::regclass)
Indexes:
    "s_pkey" PRIMARY KEY, btree (id)

切换到使用标识列的快速而干净的方法如下:

-- make the change atomic
BEGIN;

-- prevent concurrent access to the table
LOCK s;

-- get the current sequence value
SELECT last_value FROM s_id_seq;

 last_value 
════════════
       1000
(1 row)

-- get rid of the sequence
DROP SEQUENCE s_id_seq CASCADE;
NOTICE:  drop cascades to default value for column id of table s

-- turn "id" into an identity column, start the sequence a little higher
ALTER TABLE s ALTER id ADD GENERATED ALWAYS AS IDENTITY (START 1100);

-- done
COMMIT;

现在桌子没问题了:

\d s
                           Table "laurenz.s"
 Column │  Type   │ Collation │ Nullable │           Default            
════════╪═════════╪═══════════╪══════════╪══════════════════════════════
 id     │ integer │           │ not null │ generated always as identity
Indexes:
    "s_pkey" PRIMARY KEY, btree (id)
© www.soinside.com 2019 - 2024. All rights reserved.