Django "Невозможно добавить или обновить дочернюю строку: сбой внешнего ключа"

У меня есть модель Coupon и модель Photo с a ForeignKey к ней:

class Photo(models.Model):
    coupon = models.ForeignKey(Coupon,
                               related_name='description_photos')
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images')

Я установил встроенные строки в admin, так что теперь я могу добавить фотографии в купон от администратора.

Я пытаюсь добавить один, и загрузка выполнена успешно, но затем я получаю страницу отладки Django с этой ошибкой:

IntegrityError at /admin/coupon/coupon/321/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (`my_project`.`coupon_photo`, CONSTRAINT `coupon_id_refs_id_90d7f06` FOREIGN KEY (`coupon_id`) REFERENCES `coupon_coupon` (`id`))')

Что это и как я могу решить эту проблему?

(Если это имеет значение, это база данных MySQL.)

РЕДАКТИРОВАТЬ: Я попробовал это в базе данных Sqlite3, у которой немного другой набор данных, и это сработало, так что, возможно, в моей текущей базе данных есть потерянные данные? Как его найти и удалить?

Ответ 1

Некоторые из моих таблиц были в InnoDB, а некоторые из них были в MyISAM... Я изменил все на MyISAM, и проблема была решена.

Ответ 2

DATABASES = {
'default': {
    ...         
    'OPTIONS': {
         "init_command": "SET foreign_key_checks = 0;",
    },
 }
}

(Согласно официальному документу) В предыдущих версиях Django приборы с прямыми ссылками (т.е. Отношения к строкам, которые еще не были вставлены в базу данных) не будут загружаться при использовании механизма хранения InnoDB. Это связано с тем, что InnoDB отклоняется от стандарта SQL, проверяя ограничения внешнего ключа сразу же, вместо того, чтобы отложить проверку до тех пор, пока транзакция не будет выполнена. Эта проблема была решена в Django 1.4.

Ответ 3

Чтобы избежать этого, то, что вы также можете сделать, это установить STORAGE_ENGINE в settings.py

для django >= 1.2

DATABASES = {
    'default': {
        ...
        'STORAGE_ENGINE': 'MyISAM / INNODB / ETC'
    }
}

для django <= 1,2

DATABASE_STORAGE_ENGINE = "MyISAM / INNODB / ETC"

Обратите внимание, что это верно только для MySQL

Ответ 4

Я столкнулся с этой же проблемой: решение mmrs151 работает, но NB, что для Django <= 1.2 (т.е. перед поддержкой нескольких баз данных) установка выглядит следующим образом:

DATABASE_OPTIONS = {"init_command": "SET foreign_key_checks = 0;"}

Стоит отметить, что Рам Рачум, похоже, уже работал, а не решил проблему: MyISAM вообще не поддерживает транзакции...

Ответ 5

Когда-нибудь причина этой ошибки пытается сначала сохранить дочернюю таблицу, а затем сохранить родителя.
решение для этого - использование 1). DATABASES = { 'default': { ...
'OPTIONS': { "init_command": "SET foreign_key_checks = 0;", }, } }

2). Оформить свой поток операций с базой данных и сделать его родительским → дочерний

Ответ 6

Еще одна опция - удалить contraint в таблице MySQL:

alter table <TABLE_NAME> drop foreign key <CONTRAINT_NAME>;