将列添加为外键会使外键约束中引用的ERROR列不存在


78

我有以下设置,

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

我想增加一列命名senderlinks_chatpicmessage这是一个外键被称为另一个表auth_userid列。

为了实现以上目的,我正在终端上尝试以下操作:

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

但这给我一个错误:

错误:外键约束中引用的列“发件人”不存在

我该如何解决?


auth_user上列的名称是什么?
埃文·卡罗尔

我为这个问题提供了新的答案,因为我希望语法可以更好地解释stackoverflow.com/a/50681996/124486
Evan Carroll

Answers:


121

向列添加约束它需要首先存在于表中,而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。我想念一些基本的东西吗?
哈桑·拜格

1
是的,是的,向列添加约束它需要首先存在于表中,mysql中没有可用于添加列并同时添加约束的命令。它必须是两个单独的命令。使用您在注释中发布的命令,但向其中添加TYPE:ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER我在这里使用整数,但它应与auth_user (id)
Jorge Campos的

1
我会将这段文字添加到我的答案中,因为我错过I want to add a column了您的部分问题。:)
Jorge Campos

79

您可以在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一线一样,只是更具描述性...

假设您要引用表auth_user中的主键,并且该键名是'id'。

我使用以下语法:

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

注意:some_type = [类型与表auth_user中的发件人相同]


5

CONSTRAINT子句是可选的。我建议省略它,并始终让PostgreSQL自动命名约束,而无需命名它,您将获得一个逻辑名称。

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

这就是您可能想知道由于约束违反而导致INSERTUPDATE失败的原因。

添加外键的语法

所有这些都在 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);

-1

****现有列的外键参考****

ALTER TABLE table_name添加约束fkey_name外键(id)参考ref_table(id)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.