Renaming foreign-key columns in MySQL

2019-01-07 18:54发布

We're trying to rename a column in MySQL (5.1.31, InnoDB) that is a foreign key to another table.

At first, we tried to use Django-South, but came up against a known issue:

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

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

AND

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

This error 150 definitely pertains to foreign key constraints. See e.g.

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/

So, now we're trying to do the renaming in raw SQL. It looks like we're going to have to drop the foreign key first, then do the rename, and then add the foreign key back again. Does that sound right? Is there a better way, since this seems pretty confusing and cumbersome?

Any help would be much appreciated!

6条回答
贪生不怕死
2楼-- · 2019-01-07 19:33

here is the SQL syntax for regular keys

ALTER TABLE `thetable`
  DROP KEY `oldkey`, 
  ADD KEY `newkey` (`tablefield`);
查看更多
叛逆
3楼-- · 2019-01-07 19:37

This task becomes simpler if you use GUI tools. I tried to rename ID column using IntelliJ IDEA Database tool and it worked like a charm! I don't have to bother about foreign keys when renaming a table or column.

See more details in IntelliJ IDEA Help | Renaming items.

MySQL 5.7

查看更多
▲ chillily
4楼-- · 2019-01-07 19:42

AFAIK, dropping the constraint, then rename, then add the constraint back is the only way. Backup first!

查看更多
Emotional °昔
5楼-- · 2019-01-07 19:50

The following query will build the correct syntax automatically. Just execute each line returned and all your FKEYs will be gone.

I leave the reverse (adding them back) as an exercise for you.

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';
查看更多
别忘想泡老子
6楼-- · 2019-01-07 19:54

In case anyone is looking for the syntax it goes something like this:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

alter table customer_account  add constraint `FK3FEDF2CCD115CB1A` foreign key (campaign_id) REFERENCES campaign(id);
查看更多
来,给爷笑一个
7楼-- · 2019-01-07 19:55

Expanding on @Dewey's answer, here's a little script to rename FKs generated by Hibernate in a useful manner ("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_%';

A bit of output:

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);
查看更多
登录 后发表回答