尝试将现有生产数据库表列从枚举转换为VARCHAR

时间:2010-05-05 02:35:15

标签: mysql ruby-on-rails ruby activerecord mysql-error-1067

我有一个问题,需要我转换现有的实时制作(我已经在本地开发框中复制了架构,不要担心)从枚举到字符串的表列类型。

背景:

基本上,以前的开发人员使我的代码库处于绝对混乱状态:迁移版本非常过时,显然他在开发过程中的某个时间点后从未使用它,现在我的任务是迁移Rails 1.2。 6 app to 2.3.5。

我无法让测试在2.3.5上正常运行,因为我的表列具有ENUM列类型,并且它们在我的schema.rb上转换为:string:limit => 0,这会产生问题执行rake db:test:prepare时的默认值无效,如:

Mysql::Error: Invalid default value for 'own_vehicle': CREATE TABLE `lifestyles` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `member_id` int(11) DEFAULT 0 NOT NULL, `own_vehicle` varchar(0) DEFAULT 'Y' NOT NULL, `hobbies` text, `sports` text, `AStar_activities` text, `how_know_IRC` varchar(100), `IRC_referral` varchar(200), `IRC_others` varchar(100), `IRC_rdrive` varchar(30)) ENGINE=InnoDB

我正在考虑编写一个迁移任务,该任务通过所有数据库表查找包含枚举的列,并将其替换为VARCHAR,我想知道这是否是解决此问题的正确方法。或者更好的是,如果有办法解决这个问题而不必修改数据库,那就更好了!

我也不确定如何编写它以便循环遍历我的数据库表并用VARCHAR替换所有ENUM colum_types

参考

1 个答案:

答案 0 :(得分:2)

我也在寻找解决方案来修复enum的schema.rb文件,因为RoR(目前版本3.1.3)将它们称为限制为0的字符串。

看起来有一个插件/ gem用于处理枚举类型而不更改数据库。在Rails 1和2上插件:http://enum-column.rubyforge.org/ 在Rails 3上有一个类似于那个的宝石:https://github.com/electronick/enum_column

将enum_column3添加到Gemfile(并运行bundle update)或安装插件后,运行rake task db:schema:dump重新生成schema.rb文件。

我看到这个插件/ gem的唯一缺点就是你必须在应用程序中更改使用这些字段的代码(所以你必须找到它们)从字符串到符号,以及validates_inclusion_of到validates_columns。尽管如此,用grep和vi做这个并不需要太长时间。

或者你可以像罗伯特上面所说的那样直接改变MySQL,以便它与RoR所期望的相匹配。但我个人更喜欢继续使用Enum类型。 (我有一个LAMP背景。)使用模型中的validates_inclusion_of将enum作为varchar处理,对于不使用schema.rb的所有内容都非常有用。只是测试和迁移有问题。

或者,您可以继续手动编辑schema.rb文件以修复限制。 (这就是我们到目前为止所做的,但它很烦人。)

(我想我没有足够的重复点来添加评论?史蒂夫的回答让我感到烦恼。你肯定想要使用迁移,因为那样你就可以保证在开发时做同样的改动。这太简单了甚至在部署期间复制粘贴SQL时也会出错。相信我,我根据经验知道这一点。此外,迁移是保留更改的标准位置。如果从中恢复,则可能需要重新应用它们。较旧的备份。)