Додавання стовпця як зовнішнього ключа дає стовпець 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.