Додавання стовпця як зовнішнього ключа дає стовпець ERROR, на який посилається обмеження зовнішнього ключа, не існує


79

Я налаштував наступне,

CREATE TABLE auth_user ( id int PRIMARY KEY );
CREATE TABLE links_chatpicmessage ();

Я намагаюся додати стовпець з іменем, senderдо links_chatpicmessageякого є зовнішній ключ, до іншої таблиці, яка називається стовпець auth_user' id.

Щоб досягти вищесказаного, я намагаюся на терміналі:

ALTER TABLE links_chatpicmessage
  ADD FOREIGN KEY (sender)
  REFERENCES auth_user;

Але це призводить до помилки:

ПОМИЛКА: стовпець "відправник", на який посилається обмеження зовнішнього ключа, не існує

Як це виправити?


Як називається стовпець на auth_user?
Еван Керролл,

Я додав нову відповідь на це, тому що мені подобається, щоб граматика була трохи краще пояснена stackoverflow.com/a/50681996/124486
Еван Керролл,

Відповіді:


125

Щоб додати обмеження в стовпець, воно повинно існувати спочатку в таблиці. У Postgresql немає команди, яку ви можете використовувати для одночасного додавання стовпця та обмеження. Це повинні бути дві окремі команди.Ви можете зробити це за допомогою наступних команд:

Спочатку зробіть так:

ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER;

Я використовую integerтут як тип, але це повинен бути той самий тип idстовпця auth_userтаблиці.

Потім ви додаєте обмеження

ALTER TABLE links_chatpicmessage 
   ADD CONSTRAINT fk_someName
   FOREIGN KEY (sender) 
   REFERENCES auth_user(column_referenced_name);

ADD CONSTRAINT fk_someNameЧастина цієї команди іменування ваше обмеження , так що якщо ви останній на необхідності документувати його з деяким інструментом , які створюють модель ви будете мати обмеження по імені , а не випадковим ім'ям.

Крім того, він служить для адміністраторів, тому DBA знає, що обмеження є з цієї таблиці.

Зазвичай ми називаємо це з деяким натяком на те, звідки воно прийшло і де воно посилається на вашу справу fk_links_chatpicmessage_auth_user так що будь-хто, хто бачить це ім’я, точно знатиме, що це за обмеження, не роблячи складного запиту на INFORMATION_SCHEMA для з’ясування.

РЕДАГУВАТИ

Як згадується у відповіді @ btubbs, ви можете фактично додати стовпець з обмеженням в одній команді. Подобається так:

alter table links_chatpicmessage 
      add column sender integer, 
      add constraint fk_test 
      foreign key (sender) 
      references auth_user (id);

1
Привіт @HassanBaig Я відредагую свою публікацію, щоб пояснити кожну частину.
Хорхе Кампос

Розумію. +1 для пояснення. Дозвольте спробувати
Хасан Бейг

Тож я спробував, ALTER TABLE links_chatpicmessage ADD CONSTRAINT fk_links_chatpicmessage_auth_user FOREIGN KEY (sender) REFERENCES auth_user(id);але все-таки отримав column "sender" referenced in foreign key constraint does not exist. Я пропускаю щось принципове, я гадаю?
Hassan Baig

1
Так, саме для того, щоб додати обмеження до стовпця. Це потрібно, щоб воно існувало спочатку в таблиці. У mysql немає команди, яку ви можете використовувати, яка одночасно додасть стовпець і додасть обмеження. Це повинні бути дві окремі команди. Використовуйте команду, яку ви розміщуєте в коментарях, але додайте до неї ТИП, наприклад: ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGERЯ використовую ціле число тут, але це має бути той самий типauth_user (id)
Хорхе Кампос

1
Я додам цей текст у свою відповідь, бо пропустив I want to add a column частину вашого запитання. :)
Хорхе Кампос

84

Ви можете зробити це в Postgres в одному рядку:

ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER REFERENCES auth_user (id);

Не потрібно вручну встановлювати ім’я. Postgres буде автоматично називати це обмеження "links_chatpicmessage_auth_user_id_fkey".


1
Я спробував це, і це точно працює в Postgres 10. Можливо, прийнята відповідь була правильною деякий час тому, що деякий час тому ми не могли додати стовпець та обмеження зовнішнього ключа, але це, звичайно, вже не відповідає дійсності.
Працівник 11-ї години

це те, що я шукав, пам’ятаю, що це було можливо :)
skwisgaar

8

Я знаю, що ця відповідь пізня, і я усвідомлюю, що це те саме, що btubbs one-line, лише трохи більш описовий ...

Якщо припустити, що ви хочете посилатися на первинний ключ у таблиці auth_user, а ім'я цього ключа - 'id'.

Я використовую цей синтаксис:

ALTER TABLE links_chatpicmessage 
ADD COLUMN sender some_type,
ADD FOREIGN KEY (sender) REFERENCES auth_user(id);

Примітка: some_type = [введіть те саме, що і відправник у таблиці auth_user]


6

CONSTRAINTПункт НЕ є обов'язковим. Я пропоную опустити його і завжди дозволяти PostgreSQL автоматично називати обмеження, не називаючи його, ви отримаєте логічне ім'я

"links_chatpicmessage_sender_fkey" FOREIGN KEY (sender) REFERENCES auth_user(id)

Це те, що ви, мабуть, хочете знати, якщо INSERTабо UPDATEне вдається через порушення обмеження.

Синтаксис для додавання зовнішнього ключа

Все це дещо задокументовано ALTER TABLE

До нової колонки

ALTER TABLE links_chatpicmessage 
  ADD COLUMN sender int,
  ADD [CONSTRAINT foo] FOREIGN KEY (sender) REFERENCES auth_user(id);

Це складно і транзакційно. Ви можете оформити два ALTERтвердження в одній таблиці, розділивши два твердження символом a, .

До попередньої колонки

-- assumes someone has already added the column or that it already exists
ALTER TABLE links_chatpicmessage
  ADD COLUMN sender int;

ALTER TABLE links_chatpicmessage
  ADD [CONSTRAINT foo] FOREIGN KEY (sender) REFERENCES auth_user(id);

-1

**** посилання на зовнішній ключ для існуючого стовпця ****

ALTER TABLE table_name ДОДАТИ ОБМЕЖЕННЯ fkey_name ІНОЗЕМНИЙ КЛЮЧ (id) СПИСОК ЛІТЕРАТУР ref_table (id)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.