如何在 PostgreSQL 数据库迁移之前将所有序列重置为 1?
How to reset all sequences to 1 before database migration in PostgreSQL?
(PostgreSQL 9.4)
我正在将旧数据库迁移到新模式。在使用 pg_restore 从我的开发机器获取新模式(没有数据)后,我发现有些序列不是从 1 开始的。(我在开发过程中更改了多个序列以使用更高的值)。
在我开始数据库迁移之前,有没有一种编程重置所有序列的方法(其中一些不是主键) 回到 1?
感谢任何帮助或建议。
这足以满足我的需要,SETVAL manual. 在 PgAdmin 中,我想将序列限制为 public 架构中的所有序列:
SELECT SETVAL(c.oid, 1)
from pg_class c JOIN pg_namespace n
on n.oid = c.relnamespace
where c.relkind = 'S' and n.nspname = 'public'
我post这是对来这里的任何人的帮助。
您可以在循环中使用 setval
更改 seq 值,在这里您可以在 DATA_BASE_NAME
中获得所有列为 Id
的表
DO $$
DECLARE
i TEXT;
BEGIN
FOR i IN (SELECT tb.table_name FROM information_schema.tables AS tb INNER JOIN information_schema.columns AS cols ON
tb.table_name = cols.table_name WHERE tb.table_catalog='DATA_BASE_NAME'
AND tb.table_schema='public' AND cols.column_name='Id') LOOP
EXECUTE 'SELECT setval('||'"' || i || '_Id_seq"'||',1);';
END LOOP;
END $$;
您可以使用此 sql 代码:
DO $$
DECLARE
i TEXT;
BEGIN
FOR i IN (SELECT column_default FROM information_schema.columns WHERE column_default SIMILAR TO 'nextval%')
LOOP
EXECUTE 'ALTER SEQUENCE'||' ' || substring(substring(i from '''[a-z_]*')from '[a-z_]+') || ' '||' RESTART 1;';
END LOOP;
END $$;
我阅读了列的信息,并使用正则表达式来分隔序列的名称。在我查询并为每个序列使用 EXECUTE 之后。
此代码适用于您的数据库的所有序列。
有时序列不遵循某种模式。
我分享以下代码希望对您有所帮助
CREATE OR REPLACE FUNCTION
restore_sequences(schema_name in varchar)
RETURNS void AS $$
DECLARE
statements CURSOR FOR
select s.sequence_schema, s.sequence_name from
information_schema."sequences" s
where s.sequence_schema = schema_name
order by s.sequence_schema asc;
BEGIN
FOR stmt IN statements loop
execute 'SELECT SETVAL(' || ((E'\''||(select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name)||(E'\'')) || ', 1, true);';
execute 'ALTER SEQUENCE ' || ((select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name) || ' START 1';
END LOOP;
END;
$$ LANGUAGE plpgsql
;
(PostgreSQL 9.4)
我正在将旧数据库迁移到新模式。在使用 pg_restore 从我的开发机器获取新模式(没有数据)后,我发现有些序列不是从 1 开始的。(我在开发过程中更改了多个序列以使用更高的值)。
在我开始数据库迁移之前,有没有一种编程重置所有序列的方法(其中一些不是主键) 回到 1?
感谢任何帮助或建议。
这足以满足我的需要,SETVAL manual. 在 PgAdmin 中,我想将序列限制为 public 架构中的所有序列:
SELECT SETVAL(c.oid, 1)
from pg_class c JOIN pg_namespace n
on n.oid = c.relnamespace
where c.relkind = 'S' and n.nspname = 'public'
我post这是对来这里的任何人的帮助。
您可以在循环中使用 setval
更改 seq 值,在这里您可以在 DATA_BASE_NAME
Id
的表
DO $$
DECLARE
i TEXT;
BEGIN
FOR i IN (SELECT tb.table_name FROM information_schema.tables AS tb INNER JOIN information_schema.columns AS cols ON
tb.table_name = cols.table_name WHERE tb.table_catalog='DATA_BASE_NAME'
AND tb.table_schema='public' AND cols.column_name='Id') LOOP
EXECUTE 'SELECT setval('||'"' || i || '_Id_seq"'||',1);';
END LOOP;
END $$;
您可以使用此 sql 代码:
DO $$
DECLARE
i TEXT;
BEGIN
FOR i IN (SELECT column_default FROM information_schema.columns WHERE column_default SIMILAR TO 'nextval%')
LOOP
EXECUTE 'ALTER SEQUENCE'||' ' || substring(substring(i from '''[a-z_]*')from '[a-z_]+') || ' '||' RESTART 1;';
END LOOP;
END $$;
我阅读了列的信息,并使用正则表达式来分隔序列的名称。在我查询并为每个序列使用 EXECUTE 之后。 此代码适用于您的数据库的所有序列。
有时序列不遵循某种模式。
我分享以下代码希望对您有所帮助
CREATE OR REPLACE FUNCTION
restore_sequences(schema_name in varchar)
RETURNS void AS $$
DECLARE
statements CURSOR FOR
select s.sequence_schema, s.sequence_name from
information_schema."sequences" s
where s.sequence_schema = schema_name
order by s.sequence_schema asc;
BEGIN
FOR stmt IN statements loop
execute 'SELECT SETVAL(' || ((E'\''||(select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name)||(E'\'')) || ', 1, true);';
execute 'ALTER SEQUENCE ' || ((select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name) || ' START 1';
END LOOP;
END;
$$ LANGUAGE plpgsql
;