Das Hinzufügen einer Spalte als Fremdschlüssel führt dazu, dass eine ERROR-Spalte, auf die in der Fremdschlüsseleinschränkung verwiesen wird, nicht vorhanden ist

78

Ich habe folgendes eingerichtet:

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

Ich versuche, eine Spalte hinzufügen genannt senderzu links_chatpicmessagedenen ein Fremdschlüssel zu einer anderen Tabelle mit dem Namen auth_users‘ idSpalte.

Um dies zu erreichen, versuche ich Folgendes auf dem Terminal:

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

Aber das gibt mir einen Fehler:

FEHLER: Die Spalte "Absender", auf die in der Fremdschlüsseleinschränkung verwiesen wird, ist nicht vorhanden

Wie behebe ich das?

Hassan Baig
quelle
Wie heißt die Spalte in auth_user?
Evan Carroll
Ich habe eine neue Antwort darauf hinzugefügt, weil ich möchte, dass die Grammatik etwas besser erklärt wird. Stackoverflow.com/a/50681996/124486
Evan Carroll

Antworten:

121

So fügen Sie einer Spalte eine Einschränkung hinzu Es muss zuerst in der Tabelle vorhanden sein. In Postgresql gibt es keinen Befehl, mit dem Sie die Spalte hinzufügen und gleichzeitig die Einschränkung hinzufügen können. Es müssen zwei separate Befehle sein. Sie können dies mit folgenden Befehlen tun:

Machen Sie zuerst Folgendes:

ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER;

Ich verwende hier integerals Typ, aber es sollte der gleiche Typ der idSpalte der auth_userTabelle sein.

Dann fügen Sie die Einschränkung hinzu

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

Der ADD CONSTRAINT fk_someNameTeil dieses Befehls benennt Ihre Einschränkung. Wenn Sie diese also mit einem Tool dokumentieren müssen, das Ihr Modell erstellt, haben Sie eine benannte Einschränkung anstelle eines zufälligen Namens.

Es dient auch Administratoren, sodass ein DBA weiß, dass die Einschränkung aus dieser Tabelle stammt.

Normalerweise benennen wir es mit einem Hinweis darauf, woher es stammt und wo es auf Ihren Fall verweist. fk_links_chatpicmessage_auth_userJeder, der diesen Namen sieht, weiß genau, was diese Einschränkung ist, ohne eine komplexe Abfrage in INFORMATION_SCHEMA durchzuführen, um dies herauszufinden.

BEARBEITEN

Wie in der Antwort von @ btubbs erwähnt, können Sie in einem Befehl tatsächlich eine Spalte mit einer Einschränkung hinzufügen. Wie so:

alter table links_chatpicmessage 
      add column sender integer, 
      add constraint fk_test 
      foreign key (sender) 
      references auth_user (id);
Jorge Campos
quelle
1
Hallo @HassanBaig, ich werde meinen Beitrag bearbeiten, um jeden Teil zu erklären.
Jorge Campos
Aha. +1 für die Erklärung. Lass es mich versuchen
Hassan Baig
Also habe ich es versucht, ALTER TABLE links_chatpicmessage ADD CONSTRAINT fk_links_chatpicmessage_auth_user FOREIGN KEY (sender) REFERENCES auth_user(id);aber ich habe es immer noch column "sender" referenced in foreign key constraint does not exist. Ich vermisse etwas Grundlegendes, nehme ich an?
Hassan Baig
1
Ja genau das, um einer Spalte eine Einschränkung hinzuzufügen. Es muss zuerst in der Tabelle vorhanden sein. Es gibt keinen Befehl in MySQL, den Sie verwenden können, um die Spalte hinzuzufügen und die Einschränkung gleichzeitig hinzuzufügen. Es müssen zwei separate Befehle sein. Verwenden Sie den Befehl, den Sie in den Kommentaren posten, aber fügen Sie den TYP hinzu: ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGERIch verwende hier eine Ganzzahl, aber es sollte der gleiche Typ sein wieauth_user (id)
Jorge Campos
1
Ich werde diesen Text in meine Antwort aufnehmen, weil ich einen I want to add a columnTeil Ihrer Frage verpasst habe . :)
Jorge Campos
79

Sie können dies in Postgres in einer Zeile tun:

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

Sie müssen keinen Namen manuell festlegen. Postgres nennt diese Einschränkung automatisch "links_chatpicmessage_auth_user_id_fkey".

btubbs
quelle
1
Ich habe es versucht und es funktioniert auf jeden Fall in Postgres 10. Vielleicht war die akzeptierte Antwort vor einiger Zeit richtig, dass es vor einiger Zeit nicht möglich war, eine Spalte und die Fremdschlüsseleinschränkung auf einmal hinzuzufügen, aber es ist sicherlich nicht mehr wahr.
11. Stunde Arbeiter
das war es, wonach ich gesucht habe, ich erinnere mich, dass es möglich war :)
skwisgaar
8

Ich weiß, dass diese Antwort viel zu spät ist, und mir ist klar, dass dies dasselbe ist wie btubbs Einzeiler, nur ein wenig aussagekräftiger ...

Angenommen, Sie möchten auf den Primärschlüssel in der Tabelle auth_user verweisen und dieser Schlüsselname lautet 'id'.

Ich benutze diese Syntax:

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

Hinweis: some_type = [Geben Sie dasselbe wie Absender in die Tabelle auth_user ein]

Ted Spradley
quelle
5

Die CONSTRAINTKlausel ist optional. Ich schlage vor, es wegzulassen und PostgreSQL immer die Einschränkung automatisch benennen zu lassen, ohne es zu benennen, erhalten Sie einen logischen Namen

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

Das ist es, was Sie wahrscheinlich wissen möchten, wenn eine INSERToder UPDATEaufgrund einer Einschränkungsverletzung fehlschlägt.

Syntax zum Hinzufügen eines Fremdschlüssels

All dies ist etwas dokumentiert ALTER TABLE

Zu einer neuen Spalte

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

Dies ist zusammengesetzt und transaktional. Sie können zwei ALTERAnweisungen für dieselbe Tabelle ausgeben, indem Sie die beiden Anweisungen durch a trennen ,.

Zu einer bereits vorhandenen Spalte

-- 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
quelle
-1

**** Fremdschlüsselreferenz für vorhandene Spalte ****

ALTER TABLE Tabellenname ADD CONSTRAINT fkey_name AUSLÄNDISCHER SCHLÜSSEL (id) REFERENZEN ref_table (id)

Jagadeesha N.
quelle