Thêm một cột làm khóa ngoại thì cột ERROR được tham chiếu trong ràng buộc khóa ngoại không tồn tại


79

Tôi có thiết lập sau,

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

Tôi đang cố gắng để thêm một cột tên senderđể links_chatpicmessagemà là một khóa ngoại đến một bảng gọi là auth_user's idcột.

Để đạt được những điều trên, tôi đang thử các bước sau trên thiết bị đầu cuối:

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

Nhưng điều này mang lại cho tôi một lỗi:

LỖI: cột "người gửi" được tham chiếu trong ràng buộc khóa ngoại không tồn tại

Làm cách nào để sửa lỗi này?


Tên của cột trên auth_user là gì?
Evan Carroll

Tôi đã aded một câu trả lời mới này bởi vì tôi giống như ngữ pháp là một chút giải thích tốt hơn stackoverflow.com/a/50681996/124486
Evan Carroll

Câu trả lời:


125

Để thêm một ràng buộc vào một cột Nó cần phải tồn tại trước tiên trong bảng , không có lệnh nào trong Postgresql mà bạn có thể sử dụng để thêm cột và thêm ràng buộc cùng một lúc. Nó phải là hai lệnh riêng biệt. Bạn có thể làm điều đó bằng các lệnh sau:

Đầu tiên hãy làm như:

ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGER;

Tôi sử dụng integeras type ở đây nhưng nó phải là cùng một loại idcột của auth_userbảng.

Sau đó, bạn thêm ràng buộc

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

Một ADD CONSTRAINT fk_someNamephần của lệnh này là đặt tên cho ràng buộc của bạn, vì vậy nếu sau này bạn cần ghi lại nó bằng một số công cụ tạo mô hình của bạn, bạn sẽ có một ràng buộc được đặt tên thay vì một tên ngẫu nhiên.

Ngoài ra, nó phục vụ cho các mục đích của quản trị viên để A DBA biết rằng ràng buộc là từ bảng đó.

Thông thường, chúng tôi đặt tên cho nó với một số gợi ý về nguồn gốc của nó và nơi mà nó tham chiếu trong trường hợp của bạn, nó sẽ fk_links_chatpicmessage_auth_usernhư vậy để bất kỳ ai nhìn thấy tên này sẽ biết chính xác ràng buộc này là gì mà không cần thực hiện truy vấn phức tạp trên INFORMATION_SCHEMA để tìm hiểu.

BIÊN TẬP

Như đã đề cập trong câu trả lời của @ btubbs, bạn thực sự có thể thêm một cột với một ràng buộc trong một lệnh. Như vậy:

alter table links_chatpicmessage 
      add column sender integer, 
      add constraint fk_test 
      foreign key (sender) 
      references auth_user (id);

1
Xin chào @HassanBaig Tôi sẽ chỉnh sửa bài đăng của mình để giải thích từng phần.
Jorge Campos

Tôi hiểu rồi. +1 cho lời giải thích. Hãy để tôi thử nó
Hassan Baig

Vì vậy, tôi đã cố gắng ALTER TABLE links_chatpicmessage ADD CONSTRAINT fk_links_chatpicmessage_auth_user FOREIGN KEY (sender) REFERENCES auth_user(id);nhưng tôi vẫn nhận được column "sender" referenced in foreign key constraint does not exist. Tôi cho là thiếu một cái gì đó cơ bản?
Hassan Baig

1
Có chính xác như vậy, để thêm một ràng buộc vào cột Nó cần phải tồn tại trước tiên trong bảng, không có lệnh nào trong mysql mà bạn có thể sử dụng để thêm cột và thêm ràng buộc cùng một lúc. Nó phải là hai lệnh riêng biệt. Sử dụng lệnh bạn đăng trong các nhận xét nhưng thêm LOẠI vào nó như: ALTER TABLE links_chatpicmessage ADD COLUMN sender INTEGERTôi sử dụng số nguyên ở đây nhưng nó phải cùng loại vớiauth_user (id)
Jorge Campos

1
Tôi sẽ thêm văn bản này vào câu trả lời của mình vì tôi đã bỏ lỡ I want to add a columnmột phần câu hỏi của bạn. :)
Jorge Campos

84

Bạn có thể làm điều này trong Postgres trên một dòng:

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

Bạn không cần phải đặt tên theo cách thủ công. Postgres sẽ tự động đặt tên cho ràng buộc này là "links_chatpicmessage_auth_user_id_fkey".


1
Tôi đã thử điều này và chắc chắn nó hoạt động trong Postgres 10. Có thể câu trả lời được chấp nhận là đúng cách đây không lâu về việc không thể thêm cột và ràng buộc khóa ngoại trong một thời gian trước đây, nhưng nó chắc chắn không còn đúng nữa.
Giờ thứ 11 Công nhân

đó là những gì tôi đang tìm kiếm, tôi nhớ rằng điều đó hoàn toàn có thể xảy ra :)
skwisgaar

8

Tôi biết câu trả lời này là khá muộn và tôi nhận ra rằng câu trả lời này cũng giống như btubbs one-liner, chỉ là mô tả nhiều hơn một chút ...

Giả sử bạn muốn tham chiếu đến khóa chính trong bảng auth_user và tên khóa đó là 'id'.

Tôi sử dụng cú pháp này:

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

Lưu ý: some_type = [nhập giống như người gửi trong bảng auth_user]


6

Các CONSTRAINTđiều khoản là không bắt buộc. Tôi khuyên bạn nên bỏ qua nó và luôn để PostgreSQL tự động xử lý ràng buộc, không cần đặt tên nó, bạn sẽ nhận được một cái tên hợp lý

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

Đó là những gì bạn có thể muốn biết nếu một INSERThoặc UPDATEkhông thành công do vi phạm ràng buộc.

Cú pháp thêm khóa ngoại

Tất cả những điều này phần nào được ghi lại trên ALTER TABLE

Đến một cột mới

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

Đây là hợp chất và giao dịch. Bạn có thể đưa ra hai ALTERcâu lệnh trên cùng một bảng bằng cách tách hai câu lệnh bằng dấu a ,.

Đến một cột có sẵn

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

**** tham chiếu khóa ngoại cho cột hiện có ****

ALTER TABLE table_name ADD CONSTRAINT fkey_name FOREIGN KEY (id) REFERENCES ref_table (id)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.