Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 编辑外键引用的值时出现Django IntegrityError_Python_Django_Postgresql - Fatal编程技术网

Python 编辑外键引用的值时出现Django IntegrityError

Python 编辑外键引用的值时出现Django IntegrityError,python,django,postgresql,Python,Django,Postgresql,我有一个带有两个(相关)模型的应用程序,本质上是一个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 = m

我有一个带有两个(相关)模型的应用程序,本质上是一个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"
    )
   ...
现在有人拼错了一个学生的名字,想在
StudentTutorRelationshipProfile
中更改
Student\u name
,但因为已经有学生名字拼错的时间表记录,Django提出了一个错误(来自psychog):

更改此数据的好方法是什么?我也不介意更改历史时刻表,或者让它们保持原样(但不能删除它们),任何更容易/不太可能导致问题的事情。(是的,我依赖唯一的姓名和姓氏组合这一事实并不理想,但目前不会解决这一问题,除非IntegrityError的更改也需要一些迁移


我正在运行python 3.6,Django 3.0,如果这有帮助的话。

这是一个很好的例子,说明了为什么您永远不想使用可能被更新为外键的列。其他不好的外键候选项是,例如,不应该公开的数据、个人或私人数据,如姓名或社会安全号码等。此外,姓名也不是唯一的,这是非常重要的自动取消它们作为唯一标识符(如主键)的资格

使用串行主键,或者有时使用UUID或其他类型的通用自动生成标识符(除了标识行之外没有其他意义)更简单、更安全。它尤其不应包含非ASCII字符(这也会取消名称的资格)因为你永远不知道你是否需要通过一个无法处理它的系统来处理它,就像一个不会说这种语言的人(“你好,我的登录名是指鹿為馬").

在您的情况下,您可以使用ON UPDATE CASCADE声明外键,以便引用表上的更新级联到引用表。这只会消除一些麻烦,因为一行的简单更新可能会导致引用表中的大量更新

您也可以手动更新所有引用表,但会有一个时间窗口,在此期间引用将不一致。将外键约束设置为“延迟”并在单个事务中执行所有更新可能会起作用

但是,这不会更新数据库之外的内容中的标识符。例如,如果系统使用基于主键的文件名存储学生的照片,或者写入日志、打印纸张,或者将任何使用主键作为参考的内容存储在任何位置……或者如果主键用作url中的标识符,以及她的网站在链接中使用此标识符链接到你的网站…然后这些都不会更新,甚至无法更新

所以,是的,更新或重用主键是一个巨大的蠕虫,毫无益处。

一个(坏)解决方案是将外键设为空,暂时将其设为空,更新瞳孔名称保存,然后再次设置外键。这个过程太长且复杂。这次我只需要进行数据迁移,并在没有to_字段的情况下创建一个新的外键。
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".