103

I have the following set up,

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

I'm trying to add a column named sender to links_chatpicmessage which is a foreign key to another table called auth_user's id column.

To achieve the above, I'm trying the following on terminal:

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

But this gives me an error:

ERROR: column "sender" referenced in foreign key constraint does not exist

How do I fix this?

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

5 Answers5

155

To add a constraint to a column It needs to exists first into the table there is no command in Postgresql that you can use that will add the column and add the constraint at the same time. It must be two separate commands. You can do it using following commands:

First do as:

ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER;

I use integer as type here but it should be the same type of the id column of the auth_user table.

Then you add the constraint

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

The ADD CONSTRAINT fk_someName part of this command is naming your constraint so if you latter on need to document it with some tool that create your model you will have a named constraint instead of a random name.

Also it serves to administrators purposes so A DBA know that constraint is from that table.

Usually we name it with some hint about where it came from to where it references on your case it would be fk_links_chatpicmessage_auth_user so anyone that sees this name will know exactly what this constraint is without do complex query on the INFORMATION_SCHEMA to find out.

EDIT

As mentioned by @btubbs's answer you can actually add a column with a constraint in one command. Like so:

alter table links_chatpicmessage 
      add column sender integer, 
      add constraint fk_test 
      foreign key (sender) 
      references auth_user (id);
Jorge Campos
  • 22,647
  • 7
  • 56
  • 87
  • 1
    Hi @HassanBaig I will edit my post to explain each part. – Jorge Campos Feb 27 '16 at 22:32
  • I see. +1 for the explanation. Let me try it – Hassan Baig Feb 27 '16 at 22:41
  • 1
    So I tried `ALTER TABLE links_chatpicmessage ADD CONSTRAINT fk_links_chatpicmessage_auth_user FOREIGN KEY (sender) REFERENCES auth_user(id);` but I still got `column "sender" referenced in foreign key constraint does not exist`. I'm missing something fundamental I suppose? – Hassan Baig Feb 27 '16 at 22:42
  • the `FOREIGN KEY (sender)` part of the command informs the column name from your table `links_chatpicmessage` that should reference the other table. If you are seeing this error it means that your table `links_chatpicmessage` does not have a column named `sender` – Jorge Campos Feb 27 '16 at 22:44
  • Or if it do have maybe it was created with backticks so you should use `FOREIGN KEY (\`sender\`)` – Jorge Campos Feb 27 '16 at 22:45
  • Yes, that's actually what I'm trying to do: to add a *new* column called `sender` to my table which will be a foreignkey to auth_user(id). Should I create the sender column separately via `ALTER TABLE links_chatpicmessage ADD COLUMN "sender";` or something? – Hassan Baig Feb 27 '16 at 22:51
  • 1
    Yes exactly it, to add a constraint to a column It needs to exists first into the table there is no command in mysql that you can use that will add the column and add the constraint at the same time. It must be two separate commands. Use the command you post in the comments but add the TYPE to it like: `ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER` I use integer here but it should be the same type of the `auth_user (id)` – Jorge Campos Feb 27 '16 at 22:54
  • 1
    I will add this text into my answer because I missed `I want to add a column` part of your question. :) – Jorge Campos Feb 27 '16 at 22:57
  • The OP said they're using postgres, but this answer is referencing mysql. – btubbs Jan 04 '17 at 17:17
  • @btubbs This answer is a perfect fit to postgresql. Please clarify why you are saying that – Jorge Campos Jan 04 '17 at 21:16
  • @JorgeCampos though I can see you have now changed the text of your answer to name Postgres instead of Mysql, the content is still incorrect when it says "there is no command in Postgresql that you can use that will add the column and add the constraint at the same time". There is in fact syntax that will do this with a single line. See my separate answer for an example. – btubbs Jan 05 '17 at 21:38
101

You can do this in Postgres on one line:

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

You don't need to manually set a name. Postgres will automatically name this constraint "links_chatpicmessage_auth_user_id_fkey".

Gringo Suave
  • 29,931
  • 6
  • 88
  • 75
btubbs
  • 1,845
  • 1
  • 16
  • 19
  • 1
    I tried this and it works in Postgres 10 for sure. Maybe the accepted answer was right a while ago about not being able to add a column and the foreign key constraint in one go a while ago, but it certainly isn't true anymore. – 11th Hour Worker Feb 13 '19 at 18:37
  • that's what I was looking for, I remember that it was possible :) – skwisgaar Sep 28 '20 at 16:48
11

I know this answer is way late, and I realize this is the same as btubbs one-liner, just a little more descriptive ...

Assuming you want to reference the primary key in table auth_user and that key name is 'id'.

I use this syntax:

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

Note: some_type = [type the same as sender in table auth_user]

Ted Spradley
  • 3,414
  • 3
  • 22
  • 26
9

The CONSTRAINT clause is optional. I suggest ommiting it and always letting PostgreSQL autoname the constraint, without naming it you'll get a logical name

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

That's what you'll likely want to know if an INSERT or UPDATE fails due to a constraint violation.

Syntax to add a foreign key

All of these are somewhat documented on ALTER TABLE

To a new column

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

This is compound and transactional. You can issue two ALTER statements on the same table by separating the two statements with a ,.

To a preexisting column

-- 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);
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
-1

foreign key reference for existing column

ALTER TABLE table_name
ADD CONSTRAINT fkey_name
FOREIGN KEY (id)
REFERENCES ref_table(id)
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77