web-dev-qa-db-fra.com

Renommer des colonnes de clé étrangère dans MySQL

Nous essayons de renommer une colonne dans MySQL (5.1.31, InnoDB) qui est une clé étrangère vers une autre table.

Au début, nous avons essayé d’utiliser Django-South, mais nous nous sommes heurtés à un problème connu:

http://south.aeracode.org/ticket/243

OperationalError: (1025, "Erreur lors du changement de nom de './xxx/#sql-bf_4d' en './xxx/cave_event' (errno: 150)")

ET

Erreur lors du changement de nom de './xxx/#sql-bf_4b' en './xxx/cave_event' (errno: 150)

Cette erreur 150 concerne définitivement les contraintes de clé étrangère. Voir par exemple.

Que signifie l'erreur mysql 1025 (HY000): Erreur lors du changement de nom de './foo' (errorno: 150)?

http://www.xaprb.com/blog/2006/08/22/mysqls-error-1025-explained/

Nous essayons donc maintenant de renommer en SQL brut. Il semble que nous allons d'abord devoir supprimer la clé étrangère, puis renommer, puis rajouter la clé étrangère. Cela vous semble-t-il correct? Y a-t-il une meilleure façon, puisque cela semble assez déroutant et lourd?

Toute aide serait très appréciée!

44
Greg Detre

Autant que je sache, supprimer la contrainte, puis renommer, puis rajouter la contrainte est le seul moyen. Sauvegarde d'abord!

50
Dave Swersky

Si quelqu'un cherche la syntaxe, cela ressemble à ceci:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

alter table customer_account  add constraint `FK3FEDF2CCD115CB1A` foreign key (campaign_id) REFERENCES campaign(id);
25
34m0

voici la syntaxe SQL pour les clés régulières 

ALTER TABLE `thetable`
  DROP KEY `oldkey`, 
  ADD KEY `newkey` (`tablefield`);
3
monika mevenkamp

Pour en savoir plus sur la réponse de @ Dewey, voici un petit script permettant de renommer les FK générés par Hibernate de manière utile ("FK__" + table name + "__" + referenced table name).

SELECT CONCAT(
  "alter table ", TABLE_NAME, " drop foreign key ", CONSTRAINT_NAME,";\n",
  "alter table ", TABLE_NAME, " drop key ", CONSTRAINT_NAME, ";\n",
  "alter table ", TABLE_NAME, " add key FK__", table_name, "__",
      referenced_table_name, " (", column_name, ");\n",
  "alter table ", TABLE_NAME, " add constraint FK__", table_name, "__",
      referenced_table_name , " foreign key (", column_name, ") ",
      "references ", referenced_table_name,
      "(", referenced_column_name, ");"
  ) AS runMe 
FROM
  information_schema.key_column_usage
WHERE 
  TABLE_SCHEMA='myschemaname' 
  AND 
  constraint_name like 'FK_%';

Un peu de sortie:

alter table visitor_browsers drop foreign key FK_4ygermmic4fujggq1kp96dx47;
alter table visitor_browsers drop key FK_4ygermmic4fujggq1kp96dx47;
alter table visitor_browsers add key FK__visitor_browsers__websites (website);
alter table visitor_browsers add constraint FK__visitor_browsers__websites foreign key (website) references websites(id);
0
Jan Żankowski

Cette tâche devient plus simple si vous utilisez des outils graphiques. J'ai essayé de renommer la colonne ID avec IntelliJ IDEA Outil de base de données et cela a fonctionné comme un charme! Je n'ai pas à me soucier des clés étrangères pour renommer une table ou une colonne.

Voir plus de détails dans IntelliJ IDEA Aide | Renommer des articles .

MySQL 5.7

0
naXa

La requête suivante construira automatiquement la syntaxe correcte . Il suffit d'exécuter chaque ligne renvoyée et toutes vos clés FKEY auront disparu.

Je laisse l'inverse (en les rajoutant) comme un exercice pour vous.

SELECT CONCAT("alter table ", TABLE_NAME," drop foreign key `", CONSTRAINT_NAME,"`; ") AS runMe
FROM information_schema.key_column_usage 
WHERE TABLE_SCHEMA='MY_SCHEMA_NAME';
0
Dewey