Добавление столбца в качестве внешнего ключа дает столбец ERROR, на который ссылается ограничение внешнего ключа, не существует

У меня есть следующая настройка,

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;

Но это дает мне ошибку:

ОШИБКА: столбец "отправитель", на который ссылается ограничение внешнего ключа, не существует

Как это исправить?

Ответы

Ответ 1

Чтобы добавить ограничение в столбец, он должен существовать первым в таблице, в 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 этой команды называет ваше ограничение, поэтому, если вам нужно документировать его с помощью какого-либо инструмента, создающего вашу модель, у вас будет именованное ограничение вместо случайного имени.

Также он служит для целей администраторов, поэтому администратор базы данных знает, что это ограничение из этой таблицы.

Обычно мы fk_links_chatpicmessage_auth_user это с некоторым намеком на то, откуда он пришел, туда, где он ссылается на ваш случай, это будет 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);

Ответ 2

Вы можете сделать это в Postgres на одной строке:

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

Вам не нужно вручную устанавливать имя. Postgres автоматически назовет это ограничение "links_chatpicmessage_auth_user_id_fkey".

Ответ 3

Я знаю, что этот ответ довольно поздний, и я понимаю, что это то же самое, что и односторонний btubbs, просто немного более описательный...

Предполагая, что вы хотите ссылаться на первичный ключ в таблице auth_user, а это ключевое имя - "id".

Я использую этот синтаксис:

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

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

Ответ 4

Предложение 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 заявления по той же таблице, разделяя два высказываний с ,.

К существующему столбцу

-- 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);

Ответ 5

**** ссылка на внешний ключ для существующего столбца ****

ALTER TABLE table_name ADD CONSTRAINT fkey_name FOREIGN KEY (id) ССЫЛКИ ref_table (id)