rails : migration 使用

有时你在写迁移任务的时候可能会不小心写错,如果你已经执行了这个迁移任务,那么, 你就不能单纯地把它修改一下再重新执行一次, Rails 会认为这个迁移任务已经执行过了, 所以执行 rake db:migrate 时不会做任何操作。你应该先把写错的那个迁移任务回滚(可以执行 rake db:rollback),然后修改你的migration再执行 rake db:migrate 去 执行正确的版本。

新增一個 Migration 檔案

rails g migration migration_name
migration_name 常見的命名方式有Add欄位名To表格名或是Remove欄位名From表格名,不過這沒有一定,能描述目的即可。

rails generate model Product name:string description:text

rails generate migration AddPartNumberToProducts

rails generate migration AddPartNumberToProducts part_number:string

rails generate migration RemovePartNumberFromProducts part_number:string

 

對資料表做修改:

  • create_table(name, options) 新增資料表
  • drop_table(name) 移除資料表
  • rename_table(old_name, new_name) 修改資料表名稱
  • change_table 修改資料表欄位

個別修改資料表欄位:

  • add_column(table, column, type, options) 新增一個欄位
  • rename_column(table, old_column_name, new_column_name) 修改欄位名稱
  • change_column(table, column, type, options) 修改欄位的型態(type)
  • remove_column(table , column) 移除欄位

新增、移除索引:

  • add_index(table, columns, options) 新增索引
  • remove_index(table, index) 移除索引

記得將所有外部鍵 foreign key 加上索引

Rails中的型態說明MySQLPostgresSQLite3
:string 有限長度字串 varchar(255) character varying(255) varchar(255)
:text 不限長度文字 text text text
:integer 整數 int(4) integer integer
:float 浮點數 float float float
:decimal 十進位數 decimal decimal decimal
:datetime 日期時間 datetime timestamp datetime
:timestamp 時間戳章 datetime timestamp datetime
:time 時間 time time datetime
:date 日期 date date date
:binary 二進位 blob bytea blob
:boolean 布尔值 tinyint boolean boolean
:references 用來參照到其他Table的外部鍵 int(4) integer integer

下面的列表展示了sql和ruby间的数据类型对应关系:

SQLType                        Ruby Class      

int, integer                       Fixnum         

decimal, numeric             Float           

clob, blob, text                String           

interval, date                   Date   

 float, double                  Float

 char, varchar, string      String

datetime, time                Time

Boolean                           -

 

有 一个潜在的可能是关于decimal的,在数据库里,使用decimal的列来存储number和fix number型,Active Record将decimal映射成Float类的对象,尽管这样可以应用于大多数应用,浮点数是不精确的,在对这一类型的属性进行一系列操作的时候,可 能会发生舍入的错误,你也许可以使用integer类型来作为替代方案,例如,存储货币型的时候可以将元,角,分,分别存入不同的字段。做为一种选择,你 可以使用聚合(aggregations),使用多个分开的字段来构建货币类型。

 

另外,欄位也還有一些參數可以設定:

  • :null 是否允許NULL,預設是允許
  • :default 預設值
  • :limit 用於stringtextintegerbinary指定最大值

Migration 搭配的 Rake 任務

  • rake db:create 依照目前的 RAILS_ENV 環境建立資料庫
  • rake db:create:all 建立所有環境的資料庫
  • rake db:drop 依照目前的 RAILS_ENV 環境刪除資料庫
  • rake db:drop:all 刪除所有環境的資料庫
  • rake db:migrate 執行Migration動作
  • rake db:rollback STEP=n 回復上N個 Migration 動作
  • rake db:migrate:up VERSION=20080906120000 執行特定版本的Migration
  • rake db:migrate:down VERSION=20080906120000 回復特定版本的Migration
  • rake db:version 目前資料庫的Migration版本
  • rake db:seed 執行 db/seeds.rb 載入種子資料

如果需要指定Rails環境,例如production,可以輸入 RAILS_ENV=production rake db:migrate

bulk參數

:bulk => true可以讓變更資料庫欄位的Migration更有效率的執行,如果沒有加這個參數,或是直接使用add_columnrename_columnremove_column等方法,那麼Rails會拆開SQL來執行

要变更现有的数据表,可以用 create_table 的类似方法 change_table。它的用法跟create_table 差不多,但它的代码块有更多的方式。例如:

change_table :products do |t|
  t.remove :description, :name
  t.string :part_number
  t.index :part_number
  t.rename :upccode, :upc_code
end

移除了两个字段 description 和 name,创建了一个 part_number 的字符串类型字段并 为其添加了索引。最后重命名了 upccode 字段。

在一些情况下,Rails会知道如何去恢复所做的改变,使用change方法可以让我们不用同 时写updown方法。目前来说change方法只支持以下migration的定义:

  • add_column
  • add_index
  • add_timestamps
  • create_table
  • remove_timestamps
  • rename_column
  • rename_index
  • rename_table

如果你需要使用其他方法,那么你就不能使用change方法而需要同时写updown方法。

Migration里面的down方法能复原up方法所造成的变更。也就是说如果执行了up然后 再执行down,那么数据库的schema应该会没有改变。所以说,如果用up建立一个数据表, 就应该在down方法中删除它。明智的做法会使用跟up完全相反的顺便来做这些事情。

Rails提供一系列rake任务来执行migrations。第一个跟migration相关的rake任务是 rake db:migrate。它最基本有用法就是单纯地执行所有还没执行migrations的up或者 change方法。若所有migrations都执行过了,它就会直接结束。执行的顺序是按照migration 的日期。

值得注意的是执行db:migrate也会一起执行db:schema:dump,去更新db/schema.rb文件, 以便跟数据库的结构同步。

如 果你要migrate到某个特定版本,Active Record会执行所需的migrations(up,down,change) 直到到达指定的版本为上。所谓版本就是migration文件名前面的那串数字。例如要迁移到 版本20080906120000,只需执行:

$ rake db:migrate VERSION=20080906120000

如果指定的版本大于当前的版本(往上迁移),那么就会执行up方法到包含指定版本在内的 所有版本。如果是往下迁移的话则会执行所有down方法,但不包括指定版本本身。

rake db:rollback

 

如果你需要执行一个指定的migration的up或down方法,那么你可以用db:migrate:updb:migrate:down这两个任务。你只需指定版本号,就可以触发它的updown方法:

$ rake db:migrate:up VERSION=20080906120000

以上会执行20080906120000这个版本的migration的up方法。它会去确认这个migration之前有 没有跑过,所以,如果Active Record认为20080906120000已经跑过,那么执行 db:migrate:up VERSION=20080906120000将不会做任何操作。

原文地址:https://www.cnblogs.com/qinyan20/p/3643282.html