여기의 다른 답변에서 영감을 받아 시퀀스 마이그레이션을 수행하는 SQL 함수를 만들었습니다. 이 함수는 기본 키 시퀀스를 기존 시퀀스 범위 내부 또는 외부의 값 (> = 1)으로 시작하는 새 연속 시퀀스로 이동합니다.
여기서는 스키마가 같지만 값이 다른 두 데이터베이스를 하나의 데이터베이스로 마이그레이션 할 때이 함수를 사용하는 방법을 설명 합니다.
첫째, 함수 (생성 된 SQL 명령을 인쇄하여 실제로 무슨 일이 일어나고 있는지 명확하게 나타냄) :
CREATE OR REPLACE FUNCTION migrate_pkey_sequence
( arg_table text
, arg_column text
, arg_sequence text
, arg_next_value bigint -- Must be >= 1
)
RETURNS int AS $$
DECLARE
result int;
curr_value bigint = arg_next_value - 1;
update_column1 text := format
( 'UPDATE %I SET %I = nextval(%L) + %s'
, arg_table
, arg_column
, arg_sequence
, curr_value
);
alter_sequence text := format
( 'ALTER SEQUENCE %I RESTART WITH %s'
, arg_sequence
, arg_next_value
);
update_column2 text := format
( 'UPDATE %I SET %I = DEFAULT'
, arg_table
, arg_column
);
select_max_column text := format
( 'SELECT coalesce(max(%I), %s) + 1 AS nextval FROM %I'
, arg_column
, curr_value
, arg_table
);
BEGIN
-- Print the SQL command before executing it.
RAISE INFO '%', update_column1;
EXECUTE update_column1;
RAISE INFO '%', alter_sequence;
EXECUTE alter_sequence;
RAISE INFO '%', update_column2;
EXECUTE update_column2;
EXECUTE select_max_column INTO result;
RETURN result;
END $$ LANGUAGE plpgsql;
이 함수 migrate_pkey_sequence
는 다음 인수를 사용합니다.
arg_table
: 테이블 이름 (예를 들어 'example'
)
arg_column
: 기본 키 열 이름 (예를 들어 'id'
)
arg_sequence
: 시퀀스 이름 (예를 들어 'example_id_seq'
)
arg_next_value
: 마이그레이션 후 열의 다음 값
다음 작업을 수행합니다.
- 기본 키 값을 자유 범위로 이동합니다. 나는
nextval('example_id_seq')
다음과 같다고 가정한다
max(id)
과 하고 시퀀스가 1로 시작 . 이것은 또한 arg_next_value > max(id)
.
- 다음으로 시작하는 연속 범위로 기본 키 값을 이동합니다.
arg_next_value
. 키 값의 순서는 유지되지만 범위의 구멍은 유지되지 않습니다.
- 순서에 따라 다음 값을 인쇄하십시오. 이것은 다른 테이블의 열을 마이그레이션하고이 테이블과 병합하려는 경우 유용합니다.
설명하기 위해 다음과 같이 정의 된 시퀀스 및 테이블을 사용합니다 (예 : 사용 psql
).
# CREATE SEQUENCE example_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
# CREATE TABLE example
( id bigint NOT NULL DEFAULT nextval('example_id_seq'::regclass)
);
그런 다음 몇 가지 값을 삽입합니다 (예 : 3에서 시작).
# ALTER SEQUENCE example_id_seq RESTART WITH 3;
# INSERT INTO example VALUES (DEFAULT), (DEFAULT), (DEFAULT);
-- id: 3, 4, 5
마지막으로 example.id
값을 1로 시작하도록 마이그레이션합니다 .
# SELECT migrate_pkey_sequence('example', 'id', 'example_id_seq', 1);
INFO: 00000: UPDATE example SET id = nextval('example_id_seq') + 0
INFO: 00000: ALTER SEQUENCE example_id_seq RESTART WITH 1
INFO: 00000: UPDATE example SET id = DEFAULT
migrate_pkey_sequence
-----------------------
4
(1 row)
결과:
# SELECT * FROM example;
id
----
1
2
3
(3 rows)