`
like.eagle
  • 浏览: 248649 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

rake db:migrate

阅读更多

转载:http://hi.baidu.com/fengwill/blog/item/c80a8d829b0310aa6d811921.html

 

命令列表

 

rake db:migrate

命令作用:将所有未实施的迁移任务都实施到目标数据库上。

 

rake db:migrate VERSION=20080906120000

命令作用:撤销迁移任务到指定版本

迁移版本信息可以在所创建库(如elvuel_deployment数据库)下schema_info表中查看到相关记录信息。

 

rake db:migrate VERSION=0

命令作用:将数据库返回到最初状态(即,只有schema_migrations表,其他表都删除)

 

rake db:migrate VERBOSE=false  

命令作用:屏蔽migration的输出  

 

rake db:rollback

命令作用:回滚到最近的一次migration执行的状态  

 

rake db:rollback STEP=3  

命令作用:回滚最近的3次的迁移任务

 

 

一个在开发阶段很常用的命令redo:

rake db:migrate:redo

命令作用:重做迁移

 

rake db:migrate:redo STEP=3

rake db:migrate:down VERSION=9999999999

 

 

 

 

 

================================================ agile with rails ================================================

Rails鼓励敏捷,迭代的开发风格。我们不会第一次就期望得到正确的东西。相反我们会写测试,并与客户沟通以加强我们对事物的理解。

要做到这些,我们就需要大量的实践工作。我们写测试来帮助规划我们接口,以便我们能安全地进行修改,我们对应用程序源文件使用版本控制,允许我们回说溯错误,并可监视我们每天的改动。

但对于应用程序修改的另一方面来说,我们不能直接使用版本控制来管理。它就是我们在开发过程中,对应用程序中数据库schema的管理:我们添加一个表,重命名列名称等等。数据库的修改需要应用程序的代码。

很久以来,这一直是个问题。开发者(或数据库管理员)使用schema进行修改。但是,如果应用程序代码可以回溯到一个先前版本,但数据库schema的修改却不是同步的。因为数据库本身没有版本信息。

不久前,开发者以提出了多种解决这个问题的途径。一个schema保持了数据库定义语言(DDL),而DDL在版本控制下以源代码方式定义了schema。无论何时只要你修改了schema,你通过编辑这个文件来反映做出的修改。那么你会中止你的development数据库,并重新从你写的DDL中创建schema。如果你需要回溯到一周之前的话,那么你就会按这些步骤来检查应用程序代码和DDL:当你重新从DDL创建schema时,你的数据库会得到及时的回溯。

除了…..因为你每次应用DDL时,你都会中止数据库,你会丢失放在development数据库内的数据。如果我们能将数据库从版本x迁移到y就更好了?不错,Rails的migration迁移就可让你做到点。

让我们先在抽象层上看看migration迁移。假设我们有个存储定单数据的order表。有一天,我们的客户要求我们为每个定单上添加用户的邮件地址。这就包括了对应用程序代码数据库shema的修改。要处理它,我们创建了一个数据库migration迁移,在其内描述“给orders表添加一个e-mail字段”。这个migration迁移放在一个单独的文件内。我们将其与另外的应用程序文件一起放在版本控制下。然后我们对数据库使用这个migration迁移,结果列被添加到现有的orders表内。

如何正确地为数据库完成一个migration迁移呢?每次migration迁移都会有一个序号与其关联。这些序号从1开始---每个新的migration迁移都会得到下一个有效序号。Rails会记住应用给数据库migration迁移的最后一个序号。那么你会问,何时应用新的migration迁移来更新schema,它将数据库schema的序号与有效的migragion迁移序号进行比较。如果它发现migration迁移的序号大于数据库的schema,它就会应用migration迁移。

但是我们如何回溯一个先前版本的schema呢?我们通过让每个migration迁移都是可回溯的来做到这一点。每个migration迁移实例上都包含两个指令集。一套告诉Rails在应用migration迁移时对数据库做出什么修改,另一套则告诉Rails如何回溯这些修改。在orders表例子中,是添加e-mail列到表与移除列的回溯两部分。现在,要回溯一个schema,我们只要简单地告诉Rails我们需要数据库schema序号就可以了。如果当前数据库schema有个比目标序号更高的序号,则Rails会接受带有数据库当前序号的migration迁移,并使用它进行回溯。这会从schema中移除migration迁移的修改,并降低数据库的序号。它会反复执行此过程直到得到期望的数据库版本。

 

16.1 创建与运行Migration迁移

 

 

Migration迁移是应用程序db/migrate目录下的一个简单的Ruby源文件。每个migration迁移文件的名字(默认地)以三个数字和一个下划线开头。这些数字是migration迁移的关键,因为它们定义了应用哪个migration迁移的次序,它们各个migration迁移的版本号。

Depot应用程序的db/migrate目录看起像这样:

    depot> ls db/migrate

    001_create_products.rb 005_create_orders.rb

    002_add_price.rb 006_create_line_items.rb

    003_add_test_data.rb 007_create_users.rb

    004_add_sessions.rb

虽然你可以通过手工来创建这些migration迁移文件,但使用一个生成器会更容易(这会减少错误)。就像在创建Depot应用程序时看到的,实际上有两种用于创建migration迁移文件的生成器:

1、模型生成器(model generator) 创建的migration迁移,用于创建与模型关联的表(只要你不使用skip-migrations选项)。如下面例子所示,创建了名为discount的模型,同时也创建了名为add_create_discounts.rb的migration迁移。

    depot> ruby script/generate model discount

    exists app/models/

    exists test/unit/

    exists test/fixtures/

    create app/models/discount.rb

    create test/unit/discount_test.rb

    create test/fixtures/discounts.yml

    exists db/migrate

    create db/migrate/014_create_discounts.rb

2、你也可以用生成器只创建migration迁移本身。

    depot> script/generate migration add_price_column

    exists db/migrate

    create db/migrate/015_add_price_column.rb

稍后,我们会从Migration的解剖图开始,我们会看到migration迁移文件是什么。但现在,我们还是先看看如何运行migration迁移。

一、Running Migrations

使用Rake的db:migrate任务来运行migration迁移。

    depot> rake db:migrate

下面看看发生了什么,让我们深入到Rails的内部。

在Rails数据库内部,migration迁移代码管理一个名为schema_info的表。该表只有一个列,名为version,并且它只有一行记录。此schema_info表被用于记住当前的数据库版本。

当运行rake db:migrate时,任务首先会查看schema_info表。如果该表不存在,它将创建一个并且生成版本号为0的记录。若该表存在,则从表中读取版本号。

然后migration迁移代码查看db/migrate目录下的所有migration迁移文件。如果有序号(文件名的前导数字)大于当前数据库的版本号,那么会为数据库依次应用每个migration迁移文件。在最后一个migration迁移文件应用后,schema_info表的版本号会被更新为该文件的序号。

如果我们这一序号上再次运行migration迁移,则不会发生任何事。因为数据库内版本号已等于最高序号migration迁移文件的序号,所以不会应用任何migration迁移文件。

但是,如果我们随后创建了一个新的migration迁移文件,它就会有个大于数据库版本号的序号。如果我们随后运行该migration,则这个新的migration迁移文件会被运行。

你可以通过给rake db:migrate命令行应用VERSION=参数来为数据库强制指定一个特定的版本号。如果你给出的版本号高于数据库的版本号,则会以运行数据库版本的migration开始,以你指定的版本migration结束。

但是,如果命令行的版本号小于当前数据库的版本号,那么会发生不同的事情。在这些情形下,Rails查找与数据库版本匹配的migration迁移文件,并且回溯它。然后它降低版本号,查找匹配文件,再回溯它,等等,直到版本号匹配你在命令行上指定版本号。也就是说,migration迁移被向后应用以回溯schema回到你指定版本。

 

 

16.2 Migration解剖图

你通过创建Rails类ActiveRecord::Migration的子类来写一个migration迁移。你创建的类至少应该包含两个类方法up()和down()。

class SomeMeaningfulname < ActiveRecord::Migration

    def self.up

        # ...

    end

    def self.down

        # ...

    end

end

在down()方法回溯修改的同时,up()方法有责任为这个migration迁移应用schema修改。让我们做的更具体些。这儿是个migration迁移,它为orders表添加一个e_mails列。

class AddEmailColumnToOrders < ActiveRecord::Migration

    def self.up

        add_column :orders, :e_mail, :string

    end

    def self.down

        remove_column :orders, :e_mail

    end

end

看看down()方法的回溯是如何影响到up()方法的。

 

一、Column Types (列类型)

传递给add_column的第三个参数指定了数据库列的类型。 在前面例子中,我们指定e_mail列是 :string 类型。但这么做意味着什么呢?典型地数据库没有 :string 列类型。

回忆一下,Rails试图让你的应用程序不依赖于支持它运行的数据库:你可以开发使用MySQL,如果愿意也可开使用Postgres数据库的应用用程序。但不同的数据库为列类型使用了不同的名字。如果你在migration迁移中使用了一个MySQL列类型,那么这个migration迁移对Postgres数据库就不会工作。所以Rails migration迁移将你从基础数据库类型系统隔离开而使用逻辑类型。如果你迁移一个MySQL数据库,那么 :string 类型将创建一个varchar(255)类型的列。在Postgres上,同样的迁移会添加一个varing(255)类型的列。

由migration迁移支持的类型是: :binary,:boolean,:date,:datetime,:float,:integer,:string,:text,:time,和:timestamp。256页的图16-1显示了在Rails内数据库适配器对这些类型的缺省映射。使用这个图,你在一个migration迁移内,用 :integer声明的列在MySQL内基于类型int(11),在Oracle内基于number(38)来工作。

当在一个migration迁移内定义一个列时,你可指定三个选项。每个选项由key=>value对给出。

1、:null => true or false

如果为 true,则基础列被添加一个不能为null的约束(如果数据库支持的话)。

2、:limit => size

设置字段尺寸的限制。这基本上出现在用string创建数据库的列时。

3、:default => value

为列设置缺省值。如果你传递一个Ruby值(或Ruby表达式),那个值会变成列的默认值。对一些数据库,你也可以传递一个包含数据库指定表达式的字符串。

例如,指定 add_column :orders, :placed_at, :datetime, :default => Time.now 将在migration迁移运行时,设置列的默认值为日期和时间,

指定add_column :orders, :placed_at, :datetime, :default => "now()" 会设置MySQL now()函数为默认值,因此当前日期时间将被插入到任何新的行内。后面的语法很明显是数据库指定的。

下面是一些使用migration迁移类型和选项的例子:

    add_column :orders, :name, :string, :limit => 100, :null => false

    add_column :orders, :age, :integer

    add_column :orders, :ship_class, :string, :limit => 15, :default => 'priority'

    

二、Renaming Columns (重命名列)

在我们重构代码时,通常会修改我们变量的名字,以让它们更有意义。Rails的migration迁移也允许我们对数据库的列名字这样做。例如,在添加了一周之后,我们可能认为e_mail并不是那个新列最好的名字。我们可以创建一个migration迁移来重命名它。

class RenameEmailColumn < ActiveRecord::Migration

    def self.up

        rename_column :orders, :e_mail, :customer_email

    end

    def self.down

        rename_column :orders, :customer_email, :e_mail

    end

end

注意重命名列并不会删除任何与该列相关的数据。但是要小心并不是所有的数据库适配器都支持重命名的。

 

三、Changing Columns (更改列)

有时候你可能需要更改列的类型,或改变与列关联的选项。它与你使用add_column的方式一样,但指定是一个现有列的名字。我们假设order类型列当前是个integer,但我们需要更改它为string。我们想保持现有数据,所以一个123的order类型数据将变成字符串”123”。随后,我们就可使用非整数值如”new”和”existing”。

Changing from an integer column to a string is easy:

def self.up

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

end

但是,向相反方向的转换却是个问题。我们可能会试着这样写down() migration迁移:

def self.down

    change_column :orders, :order_type, :integer

end

但是如果我们的应用程序已在这个列中存储了像”new”这样的数据,down()方法将会丢失数据 --- “new”不能被转换成一个整数。如果这是可接受的,那么migration迁移就接受它。然而,如果我们想创建一个单向的migration迁移 --- 那么它就是不可逆转的 --- 你会中止向下的migration迁移。在这种情况下,Rails提供了一个你可以抛出的特殊异常。

class ChangeOrderTypeToString < ActiveRecord::Migration

    def self.up

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

    end

    def self.down

        raise ActiveRecord::IrreversibleMigration

    end

end

 

===========================

指定某个环境的数据库:

rake db:migrate RAILS_ENV="rits"

===========================

 

 

分享到:
评论

相关推荐

    capistrano-rails-db:Capistrano v3的Rails迁移任务(db

    Capistrano :: Rails :: Db Capistrano v3的Rails迁移任务: 在终端中运行cap -T deploy:db以获取迁移任务的完整列表: ...cap deploy:db:migrate # Run rake db:migrate Migrate the database (opti

    ruby创建blog

    6.rake db:migrate //数据迁移 7.Rails console //控制台 2.4.1 :004 &gt; Post =&gt; Post (call 'Post.connection' to establish a connection) 2.4.1 :005 &gt; Post.all Post Load (2.2ms) SELECT "posts".* FROM ...

    heroku-buildpack-smartmigrate:警告开发人员运行 rake db 的简单 Heroku buildpack

    简单的 Heroku buildpack 可以在检测到新迁移时巧妙地运行rake db:migrate 。 此 buildpack 旨在成为具有前面的一部分。动机很多时候,我在推送到 heroku 后忘记运行rake db:migrate ,这导致应用程序损坏。 有些人...

    rails简单实例_rake数据导入

    来自practical rails social networking sites上的第二章的实例,应用了数据导入,导入数据到mysql后就可以使用,命令: rake db:migrate(进入文件夹"railscoder")

    redmine_password_tool:Redmine 密码管理插件

    每个项目的基于角色的访问 测试 概括 在 travis-ci.org(主分支)上 测试政策 一切都应该被测试覆盖 ...rake db:drop db:create db:migrate db:test:load db:test:prepare redmine:plugins:migrate redmine:load

    ActiveRecord-Without-Rails:只是在没有Rails的情况下使用ActiveRecord迁移的简单示例

    没有Rails的ActiveRecord 只是在没有Rails的情况下使用ActiveRecord迁移的简单示例您可以执行的任务: rake db:create rake db:migrate rake db:dropRails 5+的注意事项请注意,即使使用Rails 5,您也需要rake db:...

    Fantastic4:精彩的活动视觉投票应用程序

    会员 陈玉玺倪燕英张耀仁朱千云 关键跟踪器链接开发备忘录常见的 rake 命令rake db:migrate VERSION=20080906120000 运行所需的迁移,直到达到指定的版本rake db:rollback 回滚上次迁移rake db:setup 创建数据库,...

    infoss_public

    捆绑执行rake db:migrate 捆绑包执行者佣金flush_lookup_folder捆绑包执行者佣金migrate_zga:base_setup捆绑包执行者佣金migrate_zga:exchange捆绑包执行者佣金migrate_zga:cash_bank捆绑包执行者佣金migrate_...

    recruit_stu:招生

    rake db:migrate rake db:seed 启动3000端口 rails s 访问前台 账号: 密码:11111111 访问后台 账号: 密码:11111111 创建一个类 数据表创建: rails g migration create_student_documents 执行数据库创建脚本: ...

    hypercable:具有Rails TimescaleDB OpenResty和Crystal lang的高性能可扩展Google Analytics(分析)替代品

    运行迁移:docker-compose运行rails rake db:migrate 生产设置 git克隆 编辑.env.production docker-compose -f docker-compose.production.yaml运行rails rake db:migrate docker-compose -f docker-compose....

    WomenCanMakeIt2

    创建本地数据库: $ rake db:create$ rake db:create RAILS_ENV=test 迁移数据库以使用最新的架构: $ rake db:migrate$ rake db:migrate RAILS_ENV=test测试$ rspec发展启动服务器: $ rails s 在浏览器中访问 。

    captains_log:基础架构变更日志工具

    rake db:test:prepare && rake db:migrate RAILS_ENV=test rake db:seed bundle exec guard 演示版 username: user@example.com password: password123 API开发 从Rails控制台生成API密钥: rails console Api...

    todo:简单的 JSONHAL 所有 API

    设置bundle installrake db:setup # this will generate a todos_development and todos_test dbrake db:migrate # runs the migrations in db/migrationsrake db:migrate RAKE_ENV=test # migrate test db 您可以...

    migration:来自卢甘斯克、顿涅茨克地区、克里米亚自治共和国和塞瓦斯托波尔的移民登记册

    安装:git pull RAILS_ENV=test rake db:migrate RAILS_ENV=test rake db:seed RAILS_ENV=test rake vacancy:seed RAILS_ENV=test rake koatuu:seed RAILS_ENV=测试包 RAILS_ENV=测试 rake 资产:预编译 RAILS_ENV...

    kiris:Phate Radio是有关动漫,游戏和流行音乐的实验性互联网广播

    $ bundle exec rake db:create $ bundle exec rake db:migrate $ bundle exec rake db:seed启动Web服务器: $ rails server使用浏览器,转到http://localhost:3000 ,您将看到主页。测试 $ bundle exec rake db:...

    ChallengeChampion:Rails女孩愚蠢的骇客日

    rake db:migrate rake db:test:prepare rake db:populate These commands do the following: 1. Install all of the necessary gems listed in the Gemfile 2. Create the test and development databases based ...

    makyma:突出日常产品的不同生态替代方案

    文档 :water_wave: 以下说明将帮助您入门和使用该应用程序。 先决条件 :wrench: 节点JS 适用于MacOS,Linux和Windows。...bundle exec rake db:migrate 数据库初始化 :magnifying_glass_tilted_left: 要

    tzyz:滕州一中校友会

    开始吧初始化数据库: rake db:migrate:reset && rake db:setup (或bundle exec rake db:migrate:reset && rake db:setup ) 我们将用于缓存,会话和sidekiq。 请安装并在文件中配置redis的配置( config/secrets....

    orangelight:PUL Blacklight项目

    rake db:migrate rake db:seed 您可以通过rails dbconsole -p访问数据库控制台。 在本地运行开发环境 假定所有命令都从您的本地orangelight目录运行 使用Lando启动Solr lando start 注意:您可以通过运行lando stop...

    ticket-booth:电影票应用

    migrate&gt; heroku local # run the app运行规范的步骤&gt; bundle exec dotenv rake db:migrate \[ test \]&gt; bundle exec dotenv rspecAPI文档使用邮递员应用程序导入ticket_booth_api.postman_collection.json以便与API...

Global site tag (gtag.js) - Google Analytics