Postgres:更新所有表的主键序列

Posted

技术标签:

【中文标题】Postgres:更新所有表的主键序列【英文标题】:Postgres: Update primary key sequence for all tables 【发布时间】:2018-04-03 15:35:07 【问题描述】:

我已手动将生产中的所有数据导入我的开发服务器,但出现此错误。我还阅读了here,它解决了这个问题,但仅限于一个表。我已经导入了大约 10 多个表格及其数据。这是错误:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "influences_pkey" DETAIL: Key (id)=(1) already exists. : INSERT INTO "influences" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"

【问题讨论】:

为什么不用相同的命令循环遍历 10 个表 受影响的表已经有大约 20+ 条记录。 所以只要设置主键相应启动即可。您只需将主键的起点从 1 更新到 21,下次 db 将从 21 开始 【参考方案1】:

这里是重置所有序列的 plpgsql(在 pgadmin 或 psql 或任何其他客户端中运行):

do 
$$
declare
 _r record;
 _i bigint;
 _m bigint;
begin
  for _r in (
    SELECT relname,nspname,d.refobjid::regclass, a.attname, refobjid
    FROM   pg_depend    d
    JOIN   pg_attribute a ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubid
    JOIN pg_class r on r.oid = objid
    JOIN pg_namespace n on n.oid = relnamespace
    WHERE  d.refobjsubid > 0 and  relkind = 'S'
   ) loop
    execute format('select last_value from %I.%I',_r.nspname,_r.relname) into _i;
    execute format('select max(%I) from %s',_r.attname,_r.refobjid) into _m;
    if coalesce(_m,0) > _i then
      raise info '%',concat('changed: ',_r.nspname,'.',_r.relname,' from:',_i,' to:',_m); 
      execute format('alter sequence %I.%I restart with %s',_r.nspname,_r.relname,_m+1);
    end if;
  end loop;

end;
$$
;

或使用How to reset postgres' primary key sequence when it falls out of sync?提出的任何其他解决方案

【讨论】:

感谢您的回答,但它不起作用,至少对我而言。使用 Postico,它给了我这个错误:错误:模式“_r”不存在第 1 行:SELECT coalesce(_r.nspname,'.',_r.relname'',_i,'',_m) ^ QUERY: SELECT coalesce (_r.nspname,'.',_r.relname' ',_i,' ',_m) CONTEXT: PL/pgSQL function inline_code_block line 18 at RAISE hm - 也许 Postico 不理解 DO 声明?.. _r record 被声明... 嗯,这很奇怪,它也给了我与 psql 相同的错误 @NellDavidS。抱歉 - 代码损坏。修复了一个错误 - 现在应该可以工作了 这在 12.x 上仍然可以正常工作,对于任何在 2020 年发现它的人。

以上是关于Postgres:更新所有表的主键序列的主要内容,如果未能解决你的问题,请参考以下文章

不同步时如何重置postgres的主键序列?

不同步时如何重置postgres的主键序列?

Postgres 更新不使用主键索引

需要 Debezium 连接器中用于 postgres 插入事件的主键信息

Postgres ON CONFLICT 缺少我声明支持唯一索引的主键冲突

客户坚持让可编辑列成为表的主键