在《Ruby on Rails,rake工具使用和数据库migrations迁移的概念》和《Ruby on Rails,创建和执行migrations迁移文件》中对Rails中数据库迁移的概念和迁移任务的执行做了了解。其中的迁移任务仅仅停留在创建和删除表之类最简单的操作,实际开发中还有很多对数据库结构和内容的调整。下面来了解一下:
create_table(table,options) do |t| ...columns... end
drop_table(table)
rename_table(table,new_name)
add_column(table,column,type,options)
remove_column(table,column)
rename_column(table,column,new_name)
change_column(table,column,type,options)
add_index(table,column,options)
remove_index(table,column)
execute("sql")
E:\greensoft\RailsInstaller\Sites\simple_cms>rails generate migration AlterUsers invoke active_record create db/migrate/20120706144844_alter_users.rb
在用于迁移的up方法中修改表名,增加一些字列,并修改列的属性。用户回滚的down方法中倒序添加反向操作。
class AlterUsers < ActiveRecord::Migration def up rename_table("users","admin_users") add_column("admin_users","username",:string,:limit=>25) add_column("admin_users","email",:string,:limit=>50) change_column("admin_users","email",:string,:default=>"",:limit=>100) add_column("admin_users","password",:string,:limit=>25) rename_column("admin_users","password","hashed_password") add_column("admin_users","salt",:string,:limit=>40) puts "***about to add an index ***" add_index("admin_users","username") end def down remove_index("admin_users","username") remove_column("admin_users","salt") rename_column("admin_users","hashed_password","password") remove_column("admin_users","password") remove_column("admin_users","email") remove_column("admin_users","username") rename_table("admin_users","users") end end
执行这个迁移任务
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate == AlterUsers: migrating ===================================================== -- rename_table("users", "admin_users") -> 0.0260s -- add_column("admin_users", "username", :string, {:limit=>25}) -> 0.1340s -- add_column("admin_users", "email", :string, {:limit=>50}) -> 0.1740s -- change_column("admin_users", "email", :string, {:default=>"", :limit=>100}) -> 0.1500s -- add_column("admin_users", "password", :string, {:limit=>25}) -> 0.1550s -- rename_column("admin_users", "password", "hashed_password") -> 0.1790s -- add_column("admin_users", "salt", :string, {:limit=>40}) -> 0.1540s ***about to add an index *** -- add_index("admin_users", "username") -> 0.1310s == AlterUsers: migrated (1.1361s) ============================================
改变被提交到数据库中
mysql> show fields from admin_users; +-----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | | username | varchar(25) | YES | | NULL | | | email | varchar(100) | YES | | | | | hashed_password | varchar(25) | YES | | NULL | | | salt | varchar(40) | YES | | NULL | | +-----------------+--------------+------+-----+---------+----------------+ 7 rows in set (0.02 sec)
执行成功后可以通过回滚复原到之前的状态
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate:down VERSION=20120706144844 == AlterUsers: reverting ===================================================== -- remove_index("admin_users", "username") -> 0.1360s -- remove_column("admin_users", "salt") -> 0.1490s -- rename_column("admin_users", "hashed_password", "password") -> 0.2400s -- remove_column("admin_users", "password") -> 0.1520s -- remove_column("admin_users", "email") -> 0.1370s -- remove_column("admin_users", "username") -> 0.1790s -- rename_table("admin_users", "users") -> 0.0260s == AlterUsers: reverted (1.0481s) ============================================
数据库回到了最初的状态
mysql> show fields from users; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+----------+------+-----+---------+----------------+ 3 rows in set (0.02 sec)