Я пытаюсь изменить первичный ключ одной из моих таблиц с простого на составной ключ, где составной ключ должен состоять из старого столбца pk и вновь созданного.
Я последовал за этот ответ из очень похожего вопроса: { ссылка }
Он почти работает, за исключением того, что в зависимой таблице для нового столбца нет значения.
Вот ситуация:
Предположим, у меня есть таблица для каталога и таблица для записей каталога. Раньше:
-- DDL Catalog
CREATE TABLE public.Catalog (
name_ VARCHAR(255) NOT NULL,
foo_ VARCHAR(255) NULL,
CONSTRAINT Catalog_pkey PRIMARY KEY (name_)
);
-- DDL CatalogEntry
CREATE TABLE public.CatalogEntry (
pricekey_ VARCHAR(255) NOT NULL,
pricekeyroot_ VARCHAR(255) NOT NULL,
catalog_name_ VARCHAR(255) NULL,
bar_ VARCHAR(255) NULL,
CONSTRAINT CatalogEntry_pkey PRIMARY KEY (pricekey_, pricekeyroot_)
);
-- public.CatalogEntry FOREIGN KEYs
ALTER TABLE public.CatalogEntry ADD CONSTRAINT CatalogEntry_catalog_name__fkey FOREIGN KEY (catalog_name_) REFERENCES Catalog(name_) ON DELETE CASCADE;
Итак, CatalogEntry.catalog_name
ссылки на Catalog.name_
.
Теперь мне нужно добавить еще один столбец version_
в таблицу Catalog
, указав версию какого-то каталога . Это означает, что мне нужно будет создать новый составной pk, состоящий из name_
и version_
. Вот мой сценарий:
-- UPDATE script
-- add the new version column and set all values to default of 1
ALTER TABLE Catalog ADD version_ INTEGER;
UPDATE Catalog SET version_ = 1;
ALTER TABLE Catalog ALTER column version_ SET not null;
-- update primary key and foreign key
BEGIN;
-- first, drop fkey constraint on CatalogEntry
ALTER TABLE CatalogEntry DROP CONSTRAINT CatalogEntry_catalog_name__fkey;
-- then, update Catalog primary key
ALTER TABLE Catalog DROP CONSTRAINT Catalog_pkey,
ADD CONSTRAINT Catalog_uni_name UNIQUE (name_),
ADD PRIMARY KEY (name_, version_);
-- now add new foreign key again to CatalogEntry
ALTER TABLE CatalogEntry ADD catalog_version_ INTEGER;
ALTER TABLE CatalogEntry
ADD CONSTRAINT CatalogEntry_catalog_name__catalog__fkey FOREIGN KEY (catalog_name_, catalog_version_)
references Catalog(name_, version_ ) ON DELETE CASCADE;
COMMIT;
-- finally, remove unique constraint on name since it is not needed anymore
ALTER TABLE Catalog DROP CONSTRAINT Catalog_uni_name;
После выполнения этих шагов первичный и внешний ключи кажутся установленными правильно, но значение CatalogEntry.catalog_version_
равно нулю. Соответствующее значение Catalog.version_
установлено правильно на 1.
Где моя ошибка? Нужно ли мне также вручную устанавливать CatalogEntry.catalog_version_
на 1? Я бы предположил, что он будет установлен автоматически.