database - references - Agregar una columna como clave foránea da una columna ERROR referenciada en la restricción de clave foránea no existe
postgres create table references (5)
**** referencia de clave externa para la columna existente ****
ALTER TABLE table_name ADD CONSTRAINT fkey_name FOREIGN KEY (id) REFERENCES ref_table (id)
Tengo la siguiente configuración,
CREATE TABLE auth_user ( id int PRIMARY KEY );
CREATE TABLE links_chatpicmessage ();
Estoy tratando de
agregar una columna
llamada
sender
a
links_chatpicmessage
que es una clave foránea para otra tabla llamada
auth_user
de
auth_user
.
Para lograr lo anterior, estoy intentando lo siguiente en la terminal:
ALTER TABLE links_chatpicmessage
ADD FOREIGN KEY (sender)
REFERENCES auth_user;
Pero esto me da un error:
ERROR: la columna "remitente" a la que se hace referencia en la restricción de clave externa no existe
¿Cómo puedo solucionar esto?
La cláusula
CONSTRAINT
es opcional.
Sugiero omitirlo y siempre dejar que PostgreSQL nombre automáticamente la restricción, sin nombrarlo obtendrá un nombre lógico
"links_chatpicmessage_sender_fkey" FOREIGN KEY (sender) REFERENCES auth_user(id)
Eso es lo que probablemente querrá saber si un
INSERT
o
UPDATE
falla debido a una violación de restricción.
Sintaxis para agregar una clave foránea
Todos estos están algo documentados en
ALTER TABLE
A una nueva columna
ALTER TABLE links_chatpicmessage
ADD COLUMN sender int,
ADD [CONSTRAINT foo] FOREIGN KEY (sender) REFERENCES auth_user(id);
Esto es compuesto y transaccional.
Puede emitir dos declaraciones
ALTER
en la misma tabla separando las dos declaraciones con un,.
A una columna preexistente
-- 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);
Para agregar una restricción a una columna Debe existir primero en la tabla;
no hay ningún comando en Postgresql que pueda usar que agregue la columna y agregue la restricción al mismo tiempo.
Deben ser dos comandos separados.
Puedes hacerlo usando los siguientes comandos:
Primero haz como:
ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER;
Yo uso
integer
como tipo aquí, pero debería ser el mismo tipo de la columna
id
de la tabla
auth_user
.
Luego agrega la restricción
ALTER TABLE links_chatpicmessage
ADD CONSTRAINT fk_someName
FOREIGN KEY (sender)
REFERENCES auth_user(column_referenced_name);
La parte
ADD CONSTRAINT fk_someName
de este comando es
nombrar
su restricción, por lo que si necesita documentarla con alguna herramienta que cree su modelo, tendrá una restricción con nombre en lugar de un nombre aleatorio.
También sirve para fines de administración, por lo que un DBA sabe que la restricción proviene de esa tabla.
Por lo general, lo
fk_links_chatpicmessage_auth_user
con alguna pista sobre de dónde vino a dónde hace referencia en su caso, sería
fk_links_chatpicmessage_auth_user
por lo que cualquiera que vea este nombre sabrá exactamente cuál es esta restricción sin hacer una consulta compleja en el INFORMATION_SCHEMA para averiguarlo.
EDITAR
Como se menciona en la respuesta de @ btubbs, en realidad puede agregar una columna con una restricción en un comando. Al igual que:
alter table links_chatpicmessage
add column sender integer,
add constraint fk_test
foreign key (sender)
references auth_user (id);
Puedes hacer esto en Postgres en una línea:
ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER REFERENCES auth_user (id);
No necesita establecer un nombre manualmente. Postgres nombrará automáticamente esta restricción "links_chatpicmessage_auth_user_id_fkey".
Sé que esta respuesta es muy tarde, y me doy cuenta de que es lo mismo que btubbs one-liner, solo que un poco más descriptivo ...
Suponiendo que desea hacer referencia a la clave principal en la tabla auth_user y ese nombre de clave es ''id''.
Yo uso esta sintaxis:
ALTER TABLE links_chatpicmessage
ADD COLUMN sender some_type,
ADD FOREIGN KEY (sender) REFERENCES auth_user(id);
Nota: some_type = [escriba lo mismo que el remitente en la tabla auth_user]