Migration

本文深入解析Rails中的数据库迁移机制,包括迁移文件的版本控制、强制迁移至特定版本的方法、迁移类的基本结构及其up与down方法的使用。同时介绍了如何创建、重命名及更改字段,并探讨了在实际操作过程中可能遇到的问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Creating and Running Migration

在每一個migration file 的前面,有一個三位數的數字,和一個underscore,這個三位數的數字是migration在應用時的版本值。

我們可以餵了新增一個column而新增一個migration file,如此是為了version control。可是當file 多時,會否管理又是一個問題?

當執行rake db::migrate時,這個task首先會檢查db中的schema_info table,以取得目前的version。如果schema_info不存在,則會建立這個table,並設定version 這個column的值為0。

在schema_info這個table中,只有一個column,column name為version。也只有一個row,存放目前的migration version。

如果schema_info table以存在,rails會將值讀出來,然後檢查db/migrate 目錄中所有檔案,是否有檔案的名稱的首三位數字比schema_info table中的version數字大的,如果有,則依序執行他,並改變db。當完成後,便將最後一個數字存入schema_info table中。

強制migrate到某個版本:rake db:migrate VERSION=10

如果數字大於目前的版本,則會將db/migrate目錄中,首三碼的數字是介於目前的版本號碼到指定號碼間的檔案,由小到大執行up method,修改db。

如果數字小於目前的版本,則會將db/migrate目錄中,首三碼的數字是介於目前的版本號碼到指定號碼間的檔案,由大到小執行down method,修改db。

最後都會將schema_info version的數字改為最後執行的編號。


Anatomy of a Migration


Migration class是ActiveRecord::Migration的subclass,其中需包含兩個method up 與 down。


Migration 支援的column type: binary, bo0lean, date, datetime, decimal, float, integer, string, text, time, timestamp。


每一個column有一些選項可以坐設定:

:null => true/false 如果是false,則該column不可以是null。

:limit => size 設定這個column的值得size,例如string的字元數。

Default => value 設定預設值。

在decimal這個column type另有兩個選項可以設定:precision /scale

:precision => 5 定義這個數字有幾位數

:scale => 2 定義小數點後有幾位

ex. add_column :orders, :price, :decimal, :precision=>8, :scale=>2

其範圍是999999.99~-999999.99


add_column :orders, :placed_at, :datetime, :default=>Time.now

因為default value只會在migrate執行時計算一次,所以上述的statement的預設值都是一樣的時間,就是migrate的時間。

如果要解決這個問題,只需將此column name設為created_at,type設為timestamp。


Renaming Column

我們可以利用rename_column來修改column name。

ex. rename_column :orders, :e_mail, :customer_email

其中第一個參數是table name,第二個是舊名稱,第三個是新名稱


Changing Columns

利用change_column method,我們可以修改column type,以及改變某個column的選項。

ex. 將某個type為integer的column改為integer。

def self.up

change_column :orders, :order_type, :string, :null=>false

end

如此一來,原本在這個column中的數字,就會被改為字串,ex. 123=> '123'


那self.down我們要怎麼寫呢?我們可以很直覺得寫

change_column :orders, :order_type, :integer

可是這樣會有一個問題,就是如果我們在這個column中有不是數字的值,那該怎麼辦,如果這個column可以接受null,那也許不是問題,可是如果不行呢?


這個時候我們就要讓這個migration成為不能回復的動作,Rails提供了一個特別的exception。

def self.down

raise ActiveRecord::IrreversibleMigration

end


Managing Table


Class CreateOrderHistories < ActiveRecord::Migration

def self.up

create_table :order_histories do |t|

t.column :order_id, :integer, :null=>false

t.column :create_at, :timestamp

end

end

def self.down

drop_table :order_histories

end

end


create_table method 會取得一個table name 與一個block,這個block會透過一個表格定義物件(Table definition object)來定義每一個column。


在create_table中,Migration會自動加入id這個column,並設定為primary key,所以我們無須另外定義。


在create_table中我們可以加入一些選項做設定:

force => true, migration在建立這個table前會先將同名的table刪除。

转自
http://tw.myblog.yahoo.com/weijenlu/article?mid=31&prev=33&next=30&l=a&fid=9
### 关于 Migration 的学习资料和教程 #### 数据迁移工具的学习资源 Azure DevOps Migration Tools 是一款强大的数据迁移工具,适用于企业级需求。它提供了丰富的特性,例如高效的工作项迁移、跨版本的支持以及详细的文档指导[^1]。如果希望深入研究 Azure DevOps 迁移相关内容,可以从官方文档入手,这些文档不仅涵盖了基础操作指南,还包含了高级配置选项。 对于数据库迁移领域,MySQL 提供了一个名为 MySQL Migration Toolkit 的实用程序,能够帮助开发者快速实现 Oracle 到 MySQL 的数据转换[^2]。此工具的操作相对直观,适合初学者入门。通过访问 MySQL 官方网站并下载对应的 GUI 工具包即可开始体验其功能。 另外,在数据库版本控制方面,《DB Migration 数据库版本管理工具 学习笔记》一文中提到的 `migrate` 命令及其生成 SQL 脚本的功能非常值得探索[^3]。这种基于命令行的方式灵活且易于集成到自动化部署流程中,特别适合作为团队协作的一部分来维护数据库变更记录。 #### 图形化界面与脚本编写相结合的方法论 除了传统的命令行方式外,图形化用户界面 (GUI) 同样能显著降低技术门槛。比如 Style_Migration_for_Artistic_Font_With_CNN 中介绍的内容虽然偏向艺术创作方向,但它展示了如何借助卷积神经网络(CNNs)完成特定任务的过程[^4]。尽管该项目主要关注字体样式转移,但其所采用的技术思路同样可用于其他类型的迁移场景分析。 以下是几个具体建议: - **阅读官方手册**:无论是哪种 migration 类型,始终优先查阅相关产品的正式文档。 - **观看教学视频**:许多平台都录制了详尽的教学录像,这对于理解复杂概念尤其有帮助。 - **参与在线论坛交流**:像 GitHub Discussions 或 Stack Overflow 上都有活跃的技术社区可供提问解答疑惑。 ```python # 示例 Python 脚本展示简单的文件读写过程模拟数据迁移逻辑 def migrate_data(source_file, target_file): with open(source_file, 'r') as src_f: data = src_f.read() processed_data = process(data) with open(target_file, 'w') as tgt_f: tgt_f.write(processed_data) def process(raw_content): # 实际业务处理函数定义省略... return raw_content.upper() if __name__ == "__main__": source_path = "./source.txt" destination_path = "./destination.txt" migrate_data(source_path, destination_path) ``` 以上代码片段仅作示意用途,实际应用时需考虑更多细节如错误捕获机制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值