2010-01-06 13 views
40

Estamos tratando de cambiar el nombre de una columna en MySQL (5.1.31, InnoDB) que es una clave externa a otra tabla.Cambiar el nombre de columnas de clave externa en MySQL

Al principio, intentamos utilizar Django-Sur, pero se quedó frente a un problema conocido:

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

OperationalError: (1025, "Error on rename of './xxx/#sql-bf_4d' to './xxx/cave_event' (errno: 150)")

Y

Error on rename of './xxx/#sql-bf_4b' to './xxx/cave_event' (errno: 150)

Este error 150 pertenece definitivamente al extranjero restricciones clave Ver p.

What does mysql error 1025 (HY000): Error on rename of './foo' (errorno: 150) mean?

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

lo tanto, ahora estamos tratando de hacer el cambio de nombre en SQL crudo. Parece que tendremos que soltar la clave externa primero, luego hacer el cambio de nombre, y luego volver a agregar la clave foránea. Suena bien? ¿Hay una mejor manera, ya que esto parece bastante confuso y engorroso?

¡Cualquier ayuda sería muy apreciada!

+0

posible duplicado de [? ¿Cómo puedo cambiar el nombre de una clave externa de MySQL] (http://stackoverflow.com/questions/6188011/how-do- i-rename-a-foreign-key-in-mysql) – Ben

Respuesta

41

AFAIK, soltar la restricción, luego renombrar, y luego agregar la restricción de vuelta es la única manera. Respaldo primero!

+5

Desde MySQL 5.6.6, todas las claves externas ahora se actualizan automáticamente al cambiar el nombre de una columna. http://dev.mysql.com/doc/refman/5.6/en/alter-table.html – BenL

+2

@BenL Esto no es del todo correcto. La página dice: "Antes de MySQL 5.6.6, agregar y soltar una clave externa en la misma sentencia ALTER TABLE puede ser problemático en algunos casos y, por lo tanto, no se admite. Se deben usar declaraciones separadas para cada operación. A partir de MySQL 5.6.6 , al agregar y soltar una clave externa en la misma instrucción ALTER TABLE es compatible con ALTER TABLE ... ALGORITHM = INPLACE pero permanece sin soporte para ALTER TABLE ... ALGORITHM = COPY. ". Además, he visto con mis propios ojos MySQL 5.6.2 reemplazar el nombre de la columna en un FK. Pero en mySQL 5.0.94 esto no es (todavía) posible. – hypercube

3

Ésta es la sintaxis SQL para las llaves regulares

ALTER TABLE `thetable` 
    DROP KEY `oldkey`, 
    ADD KEY `newkey` (`tablefield`); 
22

En caso de que alguien está buscando la sintaxis que es algo como esto:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

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

La siguiente consulta construirá la sintaxis correcta de forma automática. Simplemente ejecuta cada línea devuelta y todas tus FKEY desaparecerán.

Dejo el reverso (volviéndolos a agregar) como un ejercicio para ti.

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

Ampliando @ respuesta de Dewey, aquí hay un pequeño script para cambiar el nombre FKs generados por Hibernate de una manera útil ("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 poco de salida:

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); 
Cuestiones relacionadas