欢迎来我的博客http://blog.csdn.net/abbuggy/article/details/7654481
在《Ruby on Rails,rake工具使用和数据库migrations迁移的概念》中,我们知道Rails中进行数据库迁移操作的基本概念和重要性。现在着手进行一个简单的数据库迁移实践吧。
所有的数据库迁移文件存放在simple_cms/db/migrations目录中,在之前我们没有做过创建迁移的操作所以这个目录还没有生成。
有两种方式来创建迁移工作,其一是创建模型的时候migration自动生成迁移文件,其二是直接创建迁移文件。
创建模型的同时生成迁移文件:
在simple_cms应用的根目录中,执行创建模型的命令。其中User是要创建的模型的名字(注意模型的命名一般来说是单数形式,创建出来的表自动是复数形式),如此做会在创建User模型的同时创建出迁移文件。回显提示创建出了名为“YYYYMMDDHHMMSS_create_users.rb”,以时间开头下划线分割每个单词的格式。
E:\greensoft\RailsInstaller\Sites\simple_cms>rails generate model User invoke active_record create db/migrate/20120613163730_create_users.rb create app/models/user.rb invoke test_unit create test/unit/user_test.rb create test/fixtures/users.yml
class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.timestamps end end end
还可以直接创建迁移文件:
在simple_cms应用的根目录中,执行创建迁移的命令。
E:\greensoft\RailsInstaller\Sites\simple_cms>rails generate migration DoNothing invoke active_record create db/migrate/20120613163818_do_nothing.rb
打开simple_cms/db/migrations/20120613163818_do_nothing.rb,里面只有两个空方法up,和down分别对应执行这个版本的迁移和回滚这个版本的迁移。现在这个文件正如我们在名字里暗示的一样,执行迁移和回滚都是空方法什么都不干。
class DoNothing < ActiveRecord::Migration def up end def down end end
这时候我们就有了两个迁移文件,通过执行迁移工作可以让迁移文件中描述的结构及数据作用到数据库中。在执行迁移之前先看一下数据库,除了记录数据库版本的schema_migrations表之外什么都没有。
C:\Windows\system32>mysql -u abbuggy -p simple_cms_development Enter password: ******* ... mysql> SHOW TABLES; +----------------------------------+ | Tables_in_simple_cms_development | +----------------------------------+ | schema_migrations | +----------------------------------+ 1 row in set (0.00 sec) mysql>
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate == CreateUsers: migrating ==================================================== -- create_table(:users) -> 0.4120s == CreateUsers: migrated (0.4120s) =========================================== == DoNothing: migrating ====================================================== == DoNothing: migrated (0.0000s) ============================================= E:\greensoft\RailsInstaller\Sites\simple_cms>
mysql> select * from schema_migrations; +----------------+ | version | +----------------+ | 20120613163730 | | 20120613163818 | +----------------+ 2 rows in set (0.02 sec) mysql>
ActiveRecord::Schema.define(:version => 20120613163818) do create_table "users", :force => true do |t| t.datetime "created_at", :null => false t.datetime "updated_at", :null => false end end
在迁移命令后面指定版本号可以前往或回滚至指定的版本,如果输入版本号为0,回到数据库的初始状态。
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate VERSION=0 == DoNothing: reverting ====================================================== == DoNothing: reverted (0.0000s) ============================================= == CreateUsers: reverting ==================================================== -- drop_table("users") -> 0.1410s == CreateUsers: reverted (0.1420s) ===========================================
mysql> SHOW TABLES; +----------------------------------+ | Tables_in_simple_cms_development | +----------------------------------+ | schema_migrations | +----------------------------------+ 1 row in set (0.00 sec)
mysql> select * from schema_migrations; Empty set (0.00 sec)
指定某一个版本rake db:migrate VERSION=20120613163818命令将数据库前往至20120613163818执行后的状态。这里要注意,这里的“前往至”指的是从当前的版本开始执行迁移文件,直到指定的版本。换句话说,如果当前的版本为0,手头有5个迁移文件分别是1,2,3,4,5。rake db:migrate VERSION=3意味着将按顺序分别执行1,2,3版本的迁移。
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate VERSION=20120613163818 == CreateUsers: migrating ==================================================== -- create_table(:users) -> 0.1770s == CreateUsers: migrated (0.1780s) =========================================== == DoNothing: migrating ====================================================== == DoNothing: migrated (0.0000s) =============================================
如果只想执行某一个版本的迁移工作,需要使用rake db:migrate:up VERSION=xxx或rake db:migrate:down VERSION=xxx命令。比如我们可以直接执行rake db:migrate:down VERSION=20120613163730。这个命令是创建users表的逆过程,也就是删除users表。我个人觉得单独执行某一个迁移文件这不是一个明智的行为,因为有可能中间没有执行的某个迁移会影响最终的结果使得表结构或内容不同步。
E:\greensoft\RailsInstaller\Sites\simple_cms>rake db:migrate:down VERSION=20120613163730 == CreateUsers: reverting ==================================================== -- drop_table("users") -> 0.0630s == CreateUsers: reverted (0.0660s) ===========================================
不得不提的是,迁移文件只能是减少冲突,并不能完全解决冲突,更不能完全代替团队之间的沟通。如果Tom下午的迁移工作所操作的内容已经被Bob在上午的迁移工作中移除了,错误肯定是不可避免了。
关于错误回滚,有时候可能因为书写或是其他原因,迁移文件执行错误。这时候如果直接修改迁移文件至正确状态后重新执行肯定是不行的,因为Rails记录的当前迁移版本和修改的迁移文件版本相同,执行不了。正确的作法是将库回滚至上一版本后再次执行修改过的迁移文件。
欢迎来我的博客http://blog.csdn.net/abbuggy/article/details/7654481