web-dev-qa-db-fra.com

Comment désactiver temporairement une contrainte de clé étrangère dans MySQL?

Est-il possible de désactiver temporairement les contraintes dans MySQL?

J'ai deux modèles Django, chacun avec une ForeignKey à l'autre. La suppression d'instances d'un modèle renvoie une erreur en raison de la contrainte ForeignKey:

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()  #a foreign key constraint fails here

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()

Est-il possible de désactiver temporairement les contraintes et de les supprimer quand même?

530
jul

Essayez DISABLE KEYS ou 

SET FOREIGN_KEY_CHECKS=0;

assurez-vous de

SET FOREIGN_KEY_CHECKS=1;

après.

1255
Andrew Campbell

Pour désactiver globalement la contrainte de clé étrangère, procédez comme suit:

SET GLOBAL FOREIGN_KEY_CHECKS=0;

et rappelez-vous de le reculer lorsque vous avez terminé

SET GLOBAL FOREIGN_KEY_CHECKS=1;

AVERTISSEMENT: vous ne devez effectuer cette opération que lorsque vous effectuez une maintenance en mode utilisateur unique. Comme cela pourrait entraîner une incohérence des données. Par exemple, cela sera très utile lorsque vous téléchargez une grande quantité de données en utilisant une sortie mysqldump.

116
berniey

Normalement, je ne désactive les contraintes de clé étrangère que lorsque je veux tronquer une table, et comme je reviens toujours sur cette réponse, c'est pour moi à l'avenir:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;
42
AntonioCS

Au lieu de désactiver votre contrainte, modifiez-la de manière permanente sur ON DELETE SET NULL. Cela produira un résultat similaire et vous n’auriez pas besoin d’activer ou de désactiver la vérification des clés. Ainsi:

ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; //get rid of current constraints
ALTER TABLE tablename2 DROP FOREIGN KEY fk_name2;

ALTER TABLE tablename1 
  ADD FOREIGN KEY (table2_id) 
        REFERENCES table2(id)
        ON DELETE SET NULL  //add back constraint

ALTER TABLE tablename2 
  ADD FOREIGN KEY (table1_id) 
        REFERENCES table1(id)
        ON DELETE SET NULL //add back other constraint

Lisez-le ( http://dev.mysql.com/doc/refman/5.5/fr/alter-table.html ) et ceci ( http://dev.mysql.com/doc /refman/5.5/fr/create-table-foreign-keys.html ).

24
dnagirl

Pour désactiver globalement la contrainte de clé étrangère:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;

et pour la contrainte de clé étrangère active

SET GLOBAL FOREIGN_KEY_CHECKS = 1;
8
Umar Tariq

Une solution très simple avec phpmyadmin: dans votre table, allez dans l’onglet SQL, après avoir édité la commande SQL que vous voulez exécuter, à côté de GO se trouve une case à cocher 'Activer les contrôles de clé étrangère'. Désactivez cette case à cocher et exécutez votre SQL. Il sera alors automatiquement revérifié.

6
svin

Si le champ de clé est nullable, vous pouvez également définir la valeur sur null avant de tenter de le supprimer:

cursor.execute("UPDATE myapp_item SET myapp_style_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed() 

cursor.execute("UPDATE myapp_style SET myapp_item_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed()

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()
3
Chanoch

Pour moi, SET FOREIGN_KEY_CHECKS=0; ne suffisait pas… .. j'avais toujours un com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException.

Je devais ajouter ALTER TABLE myTable DISABLE KEYS;.

Alors:

SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE myTable DISABLE KEYS;
DELETE FROM myTable;
ALTER TABLE myTable ENABLE KEYS;
SET FOREIGN_KEY_CHECKS=1;
1
RotS

Définir une contrainte de clé étrangère sur 0 n’est pas une bonne idée, car si vous le faites, votre base de données n’assurera pas qu’elle ne viole pas l’intégrité référentielle. Cela pourrait conduire à des données inexactes, trompeuses ou incomplètes.

Vous créez une clé étrangère pour une raison: parce que toutes les valeurs de la colonne enfant doivent être identiques à une valeur de la colonne parent. S'il n'y a pas de contrainte de clé étrangère, une ligne enfant peut avoir une valeur qui ne figure pas dans la ligne parent, ce qui entraînerait des données inexactes.

Par exemple, supposons que vous ayez un site Web sur lequel les étudiants puissent se connecter et que chaque étudiant doive s'inscrire pour un compte en tant qu'utilisateur. Vous avez une table pour les identifiants d'utilisateur, avec l'identifiant d'utilisateur en tant que clé primaire; et une autre table pour les comptes d’élèves, avec l’identité de l’élève sous forme de colonne. Étant donné que chaque élève doit avoir un identifiant utilisateur, il serait logique de lui attribuer une clé étrangère faisant référence à l'identifiant d'utilisateur de la clé primaire dans la table des identifiants. S'il n'y a pas de vérification de clé étrangère, un étudiant peut avoir un identifiant d'étudiant et aucun identifiant d'utilisateur, ce qui signifie qu'un étudiant peut obtenir un compte sans être un utilisateur, ce qui est faux.

Imaginez si cela arrive à une grande quantité de données. C'est pourquoi vous avez besoin de la vérification de la clé étrangère.

Il est préférable de déterminer la cause de l'erreur. Très probablement, vous essayez de supprimer d'une ligne parent sans supprimer d'une ligne enfant. Essayez de supprimer de la ligne enfant avant de supprimer de la ligne parent. 

0
Valencia Starr

Dans phpMyAdmin, vous pouvez sélectionner plusieurs lignes, puis cliquez sur l'action de suppression. Vous entrerez dans un écran qui répertorie les requêtes de suppression, vous pouvez décocher la case Clé étrangère et cliquer sur Oui pour les exécuter. 

Cela vous permettra de supprimer des lignes même s'il existe une contrainte de restriction ON DELETE. 

0
Julian