簡體   English   中英

編輯外鍵引用的值時出現 Django IntegrityError

[英]Django IntegrityError when editing a value referenced by a foreign key

我有一個包含兩個(相關)模型的應用程序,本質上是一個 CRM:

class StudentTutorRelationshipProfile(models.Model):
    pupil_name = models.CharField(max_length=100, unique=True)
    parent_name = models.CharField(max_length=100)
    ...

class TimeSheet(models.Model):
    user = models.ForeignKey(
        User, on_delete=models.PROTECT, limit_choices_to={"is_tutor": True}
    )
    student = models.ForeignKey(
        StudentTutorRelationshipProfile, on_delete=models.CASCADE, to_field="pupil_name"
    )
   ...

現在有人拼錯了一個學生的名字,想在pupil_name中更改它的 student_name,但是因為已經有 TimeSheet 記錄的學生名字拼錯了, StudentTutorRelationshipProfile引發了一個錯誤(來自psychog):

ForeignKeyViolation: update or delete on table "invoicing_studenttutorrelationshipprofile" violates foreign key constraint "invoicing_timesheet_student_id_07889dc0_fk_invoicing" on table "invoicing_timesheet"
DETAIL:  Key (pupil_name)=(Student Name) is still referenced from table "invoicing_timesheet".

  File "django/db/backends/base/base.py", line 243, in _commit
    return self.connection.commit()

IntegrityError: update or delete on table "invoicing_studenttutorrelationshipprofile" violates foreign key constraint "invoicing_timesheet_student_id_07889dc0_fk_invoicing" on table "invoicing_timesheet"
DETAIL:  Key (pupil_name)=(Student Name) is still referenced from table "invoicing_timesheet".

更改此數據的好方法是什么? 我也不介意更改歷史時間表或將它們保留原樣(但不能刪除它們),這更容易/不太可能導致問題。 (是的,我依賴唯一的姓名和姓氏組合這一事實並不理想,但目前不會解決這個問題,除非 IntegrityError 的更改也需要一些遷移。

如果有幫助,我正在運行 python 3.6、Django 3.0。

這是一個很好的例子,說明了為什么您永遠不想使用可能被更新為外鍵的列。 其他不良外鍵候選者是,例如,不應公開的數據、個人或私人數據(如姓名或社會保險號等)。此外,名稱不是唯一的,這會自動取消它們作為主標識符等唯一標識符的資格鑰匙。

使用 SERIAL 主鍵或有時使用 UUID 或其他類型的通用、自動生成的標識符更簡單、更安全,除了標識行之外沒有其他意義。 它尤其不應包含非 ASCII 字符(這也使名稱不合格),因為您永遠不知道是否可能必須通過無法處理它的系統對其進行 pipe 處理,就像不會說相關語言的人一樣( “你好,我的登錄名是指鹿為馬”)。

在您的情況下,您可以使用 ON UPDATE CASCADE 聲明您的外鍵,以便引用表上的更新級聯到引用表。 這只會消除一些煩惱,因為對一行的簡單更新可能會導致引用表中的大量更新。

您也可以手動更新所有引用表,但有時 window 期間引用將不一致。 將外鍵約束設置為 DEFERRED 並在單個事務中進行所有更新可能會起作用。

但是,這不會更新數據庫外部內容中的標識符。 例如,如果系統使用基於主鍵的文件名存儲學生的照片,或者寫入日志、打印紙或存儲任何使用主鍵作為參考的任何地方......或者如果主鍵用作url 中的標識符,以及其他網站使用鏈接中的此標識符鏈接到您的標識符......然后這些都不會更新,甚至可以更新。

所以,是的,更新或重用主鍵是一大堆蠕蟲,絕對沒有任何好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM