我一直在使用
pgloader
从 MariaDB 迁移到 PostgreSQL
如果我执行
pgloader
来迁移数据库并加载我的程序,一切都会正常;我可以插入一个新的 Post
作为示例
然后我尝试使用
将学说与新数据库同步docker exec -ti app php bin/console doctrine:migrations:sync-metadata-storage
docker exec -ti app php bin/console make:migration
docker exec -ti app php bin/console doctrine:migrations:migrate
迁移后,如果我尝试插入新的
Post
,我会收到错误:
SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "idx_16660_primary"
DETAIL: Key (id)=(1) already exists.
我不确定是什么原因造成的。
查看迁移文件,我可以看到:
$this->addSql('ALTER TABLE post ALTER id TYPE INT');
$this->addSql('ALTER TABLE post ALTER id DROP DEFAULT');
$this->addSql('ALTER TABLE post ALTER id ADD GENERATED BY DEFAULT AS IDENTITY');
如果我从迁移文件中删除最后两行
ALTER id DROP DEFAULT
和ALTER id ADD GENERATED BY DEFAULT AS IDENTITY
那么它可以工作,但我的数据库不再同步
这是我的实体的典型 ID 声明
/**
* @var int
*/
#[ORM\Column(name: 'id', type: 'integer', nullable: false)]
#[Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
private $id;
语句 “ALTER TABLE post ALTER id ADD GENERATED BY DEFAULT AS IDENTITY” 将 的初始值设置为其默认值 1。显然,您需要在迁移后重置此值。完成此操作:
ALTER TABLE <table name>
ALTER COLUMN <column_name> RESTART WITH <value>;
如果您有多个表或预计需要多次执行此操作,则创建一个过程来执行此操作(请参阅demo了解每个表的示例)。
create or replace procedure post_migration_resync(table_name_in text
, id_column_in text
)
language plpgsql
as $$
declare
k_select_max_id constant text =
'select max(%I) from %I';
k_alter_key_seq constant text =
'alter table %I alter column %I restart with %s';
l_current_max integer;
l_statement text;
begin
l_statement = format(k_select_max_id,id_column_in,table_name_in);
raise notice '%',E'GET CURRENT MAX:\n ' || l_statement;
execute l_statement into l_current_max;
l_current_max = l_current_max + 10; -- set for new sequence
l_statement = format(k_alter_key_seq,table_name_in,id_column_in,l_current_max);
raise notice '%',E'SET NEW SEQUENCE:\n ' || l_statement;
execute l_statement;
commit;
end;
$$;