Django CASCADE удаление не работает и бросает IntegrityError
Я столкнулся с этой ошибкой с каскадным удалением, что очень расстраивает, поскольку я не смог понять, в чем причина. Я использую PostgresQL и у меня есть следующие модели базы данных:
class Subdomains(models.Model):
subdomainid = models.AutoField(db_column='subdomainid', primary_key=True)
class Meta:
managed = True
db_table = 'subdomains'
class Dns(models.Model):
dnsid = models.AutoField(db_column='dnsid', primary_key=True)
subdomainid = models.ForeignKey(Subdomains,on_delete=models.CASCADE, db_column='subdomainid')
class Meta:
managed = True
db_table = 'dns'
class Issues(models.Model):
issueid = models.AutoField(db_column='issueid', primary_key=True)
class Meta:
managed = True
db_table = 'issues'
class Alerts(models.Model):
alertid = models.AutoField(db_column='alertid', primary_key=True)
subdomainid = models.ForeignKey(Subdomains,on_delete=models.CASCADE, blank=True, null=True, db_column='subdomainid')
dnsid = models.ForeignKey(Dns,on_delete=models.CASCADE, blank=True, null=True, db_column='dnsid')
issueid = models.ForeignKey(Issues,on_delete=models.CASCADE, blank=True, null=True, db_column='issueid') # FK can be null
class Meta:
managed = True
db_table = 'alerts'
Когда я пытаюсь удалить объект из Subdomains таблицы следующим образом:
Subdomains.objects.filter(subdomainid=1).delete()
выдает следующую ошибку:
django.db.utils.IntegrityError: update or delete on table "subdomains" violates foreign key constraint "alerts_subdomainid_be56ec78_fk_subdomains_subdomainid" on table "alerts"
DETAIL: Key (subdomainid)=(1) is still referenced from table "alerts".
Обратите внимание, что я использовал on_delete=models.CASCADE, а внешние ключи в таблице Alerts могут быть и null.
Я думаю, что проблема может заключаться в связи между Dns и Alerts. Если я правильно понимаю, Subdomain имеет много Alerts, Dnss и Issues. В то же время, Dns имеет много оповещений.
Если субдомен удален, и через models.CASCADE вы удалите экземпляр Dns, на который ссылается экземпляр Alert, вы получите IntegrityError, потому что он был удален раньше экземпляра Alert, который на него ссылается.
Я предлагаю установить поле dnsid в модели Alerts как on_delete=models.SET_NULL.
Дайте мне знать, если я что-то неправильно понял.