Как временно отключить ограничение внешнего ключа в MySQL?
Заголовок: Как временно отключить ограничения внешних ключей в MySQL?
Описание проблемы: У меня есть две модели Django, каждая из которых имеет внешние ключи к другой. При попытке удалить экземпляры одной из моделей возникает ошибка из-за ограничения внешнего ключа:
cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed() # здесь срабатывает ошибка ограничения внешнего ключа
cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()
Существует ли возможность временно отключить ограничения внешних ключей и выполнить удаление?
5 ответ(ов)
Попробуйте использовать DISABLE KEYS
или
SET FOREIGN_KEY_CHECKS=0;
Не забудьте выполнить
SET FOREIGN_KEY_CHECKS=1;
после завершения операций, чтобы восстановить проверки внешних ключей.
Чтобы временно отключить проверку внешних ключей на глобальном уровне, выполните следующие команды:
SET GLOBAL FOREIGN_KEY_CHECKS=0;
Не забудьте включить её обратно, когда закончите:
SET GLOBAL FOREIGN_KEY_CHECKS=1;
ПРЕДУПРЕЖДЕНИЕ: Данный метод следует использовать только в режиме обслуживания с одним пользователем, так как это может привести к несовместимости данных. Это может быть особенно полезно при загрузке большого объёма данных из файла mysqldump.
Я обычно отключаю ограничения внешних ключей только когда хочу обрезать таблицу. Так как я постоянно возвращаюсь к этому ответу, это для моего будущего:
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;
Не забудьте о том, что после отключения проверок внешних ключей целостность данных может быть нарушена, так что используйте этот подход с осторожностью.
Чтобы отключить проверку внешних ключей глобально, используйте следующую команду:
SET GLOBAL FOREIGN_KEY_CHECKS = 0;
Для включения проверки внешних ключей обратно используйте:
SET GLOBAL FOREIGN_KEY_CHECKS = 1;
Обратите внимание, что данная настройка изменяет поведение для всех сессий, и следует использовать её с осторожностью, чтобы избежать несоответствий в целостности данных.
Вместо того чтобы отключать вашу зависимость, лучше навсегда изменить её на ON DELETE SET NULL. Это позволит достичь аналогичного результата, и вам не придётся постоянно включать и отключать проверку ключей. Вот пример того, как это можно сделать:
ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; // удалить текущие ограничения
ALTER TABLE tablename2 DROP FOREIGN KEY fk_name2;
ALTER TABLE tablename1
ADD FOREIGN KEY (table2_id)
REFERENCES table2(id)
ON DELETE SET NULL; // добавить ограничение с обновлёнными параметрами
ALTER TABLE tablename2
ADD FOREIGN KEY (table1_id)
REFERENCES table1(id)
ON DELETE SET NULL; // добавить другое ограничение с обновлёнными параметрами
Попробуйте также ознакомиться с этой статьёй (http://dev.mysql.com/doc/refman/5.5/en/alter-table.html) и этой (http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html).
Как выполнить фильтрацию запросов в Django по условию "не равно"?
В чем разница между null=True и blank=True в Django?
Как предотвратить SQL-инъекции в PHP?
Как сбросить AUTO_INCREMENT в MySQL
Получение последней записи в каждой группе - MySQL