Django иногда не каскадирует при удалении

#python #mysql #django

#python #mysql #django

Вопрос:

У меня есть следующие соответствующие модели

 class GameOddORM(models.Model):
    game = models.ForeignKey(GameORM, on_delete=models.CASCADE, related_name='odds')
    # ...
    objects = GameOddQuerySet.as_manager()
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['game', ...], name='unique_game_odd_idx')
        ]
        db_table = 'game_odds'


class GameOddDifferenceORM(models.Model):
    game_id = models.BigIntegerField(null=False)
    left_odd = models.ForeignKey(GameOddORM, on_delete=models.CASCADE, related_name='left_odd_diff')
    right_odd = models.ForeignKey(GameOddORM, on_delete=models.CASCADE, related_name='right_odd_diff')
    value = models.FloatField()
    class Meta:
        constraints = [
            models.Index(fields=['game_id'], name='diff_by_game_idx')
        ]
        db_table = 'game_odds_difference'

 

Иногда вызов GameOddORM.objects.filter(...).delete() (нет подзапросов) приводит к следующему исключению

 django.db.utils.IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`betsbot_db`.`game_odds_difference`, CONSTRAINT `game_odds_difference_left_odd_id_1043dadb_fk_game_odds_id` FOREIGN KEY (`left_odd_id`) REFERENCES `game_odds` (`id`))')
 

Эта ошибка сообщает мне, что строка game_odds не может быть удалена, потому что в game_odds_difference ссылке на нее есть внешний ключ. Ну, я установил ON DELETE CASCADE в GameOddsDifferenceORM модели, так что ошибка не должна возникать, на самом деле это случается только иногда. Это заставляет меня думать, что это проблема параллелизма, потому GameOddORM что вставки и удаления выполняются одновременно. Не удается ли Django эмулировать ON DELETE CASCADE , потому что после удаления строк game_odds_difference между ними могут быть добавлены новые строки?

В базе данных нет триггеров, и я не делаю необработанные запросы. Я использую Django 2.2.12, mysqlclient 1.4.6, MySQL 8.0.21, ядро базы данных InnoDB и Python 3.8.6

Комментарии:

1. Есть ли в вашей базе данных какие-либо триггеры? или вы вручную удаляли записи?

2. @WillemVanOnsem у него нет триггеров, и я не выполняю никаких необработанных запросов SQL.

3. Вы уверены, что миграции обновлены?

4. @Laggs Да, python manage.py showmigrations показывает, что все применены, и makemigrations не обнаруживает изменений.

5. Происходит ли это только тогда, когда оба left_odd и right_odd ссылаются на один и тот же объект? Я бы также просто дважды проверил миграции, которые вы выполнили, и убедился, что у них есть правильные каскады.