在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在《Ruby on Rails,rake工具使用和数据库migrations迁移的概念》中,我们知道Rails中进行数据库迁移操作的基本概念和重要性。现在着手进行一个简单的数据库迁移实践吧。 所有的数据库迁移文件存放在simple_cms/db/migrations目录中,在之前我们没有做过创建迁移的操作所以这个目录还没有生成。 有两种方式来创建迁移工作,其一是创建模型的时候自动生成迁移文件,其二是直接创建迁移文件。 创建模型的同时生成迁移文件: 在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
我们注意到从Rails3.1版本之后,生成的迁移文件中使用了更智能的change方法来代替传统的up和down方法。推荐只在change方法中加入与数据库结构相关的操作,这样即使不写回滚方法Rails也能在收到回滚命令时做出正确的操作,简直太贴心了!
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.timestamps
end
end
end
还可以直接创建迁移文件: 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>
执行迁移命令,没有参数的rake db:migrate会将没有执行过的迁移文件按照时间顺序执行一遍。CreateUsers的作用是创建一个叫做users的表,DoNothing什么都不干。
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) ===========================================
最后说说迁移文件名开头的时间戳,也就是迁移文件的版本。为什么要用一个精确到秒的时间作为迁移文件的版本呢?如果Bob早上10点创建了一个模型同时生成了当时为版本的迁移文件,后来Tom下午五点创建了另一个迁移文件。他们两个人之后分别检出代码并执行数据库迁移db:migrate时,Rails会自动按照顺序执行迁移操作保证数据库状态正确。时间版本能让团队中开发人员创建的迁移文件能够按照顺序执行,减少冲突的可能。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论