Почему в реальном мире не удастся удалить каскад модели Django? - PullRequest
3 голосов
/ 02 августа 2011

Учитывая модели Django:


class ContainerOwner(models.Model):
  id = models.IntegerField()

class Container(models.Model):
  owner = models.ForeignKey(ContainerOwner)

Если вы вызовите .delete () для объекта «ContainerOwner», он будет каскадно удалять все объекты «Контейнера», принадлежащие этому «ContainerOwner».

Но я обнаружил, что в моем реальном проекте django бывают случаи, когда это каскадное удаление кажется неудачным.Кажется, что это происходит спорадически и когда система находится под большим объемом.Таким образом, вы получите объекты «Container», у которых нет действительного «ContainerOwner» после удаления «ContainerOwner» (это должно быть невозможно, «Containers» всегда имеет «ContainerOwner».)

Кто-нибудь виделэтот тип отказа раньше и можете объяснить, как это происходит?Может ли каскадное удаление быть уничтожено на полпути в процессе каскадного удаления приложением или сервером БД?

Обновления вопроса на основе обратной связи:

1) Мы используем myisam с MySQL

2) Мы используем delete queryset для удаления набора запросов «ContainerOwner»objects

3) MySQL backend

4) У нас есть очень распространенное действие, когда набор запросов Django объектов «ContainerOwner» удаляется сразу и все их объекты «Контейнера» также должныбыть удаленным.Это происходит десятки раз в день, и мы просто замечаем, что есть эти потерянные объекты «Контейнер», вызывающие ошибки приложения.Похоже, что очень очень небольшой процент удалений завершается неудачно, например, 0,01% удалений приводят к появлению некоторых сирот.

Ответы [ 2 ]

2 голосов
/ 02 августа 2011

На самом деле невозможно ответить на ваш настоящий вопрос, не зная гораздо больше подробностей о вашем приложении, например:

  1. Есть ли у вас какая-либо логика в ContainerOwner.delete() или Container.delete()?
  2. Вы используете delete набора запросов где-нибудь, в ContainerOwner?
  3. Какую базу данных вы используете ??
  4. Общая схема использования при создании / обновлении / удалении ContainerOwner / Container объектов

Но самое главное:

"Container" objects that have no valid "ContainerOwner" after the "ContainerOwner" has been deleted

Это не должно быть возможным в первую очередь на уровне базы данных , если вы не пропустите ограничения внешнего ключа или не используете БД, которая не поддерживает ограничения FK (например, MySQL + MYISAM). Если это первое, вы должны исправить это в первую очередь. Если это последнее, рассмотрите возможность переключения, в зависимости от того, насколько это важно для вашего приложения.

0 голосов
/ 07 августа 2011

Если кто-то еще добавил контейнер, имеющий тот же ContainerOwner, и вы находитесь за пределами транзакции, он не сможет удалиться.При таких обстоятельствах вы должны получить IntegrityError.

Кроме того, если у вас есть какой-либо код, выходящий за пределы django, и существуют другие конфликтующие ограничения базы данных, то это предотвратит каскадное удаление.

Попробуйте проверить журналы базы данных и посмотрите, почему удаление не удалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...