Rails应用程序使用现有数据库MySQL

时间:2016-05-31 10:50:04

标签: mysql ruby-on-rails

我是一名RoR开发人员,我习惯使用scaffold等创建自己的数据库。但是我被告知要为现有的填充数据库创建一个rails应用程序。我搜索过,我发现了这个:

1. write config/database.yml to reference your database.
2. Run "rake db:schema:dump" to generate db/schema.rb.  Here's the
documentation:

 $ rake -T db:schema:dump
...
rake db:schema:dump # Create a db/schema.rb file that can be
portably used against any DB supported by AR

3. Convert schema.rb into db/migrate/001_create_database.rb:

Class CreateMigration < ActiveRecord::Migration
def self.up
# insert schema.rb here
end

def self.down
# drop all the tables if you really need
# to support migration back to version 0
end
end

但是我看到一些评论说他们丢失了数据,有些人说它有效。我不能冒险从数据库中丢失数据。有人可以给我一些更可靠的解释吗?或者更好的解决方案

2 个答案:

答案 0 :(得分:1)

Rails检查db / migrate /中的所有迁移文件,并检查它们是否都是“schema_migrations”表的一部分。上面的代码仅适用于代码的新副本(即,如果我克隆您的Rails项目),因为迁移按文件名的顺序运行。因为它是00001_create_d ...然后它将是我的第一个被运行,然后是你拥有的其他迁移文件。

如果您迁移,那么您可能会丢失数据,因为您的架构代码将在迁移所有迁移文件后运行。

既然只有你和其他开发人员在这个项目上工作,谁不能简单地只做rake db:migrate,并且项目的新克隆者上面的代码没有问题,那么我可以做以下事情下面强制001_create_database.rb已经是你的schema_migrations表的一部分,从而跳过它,但不是新克隆者(比如我自己)。

重要提示:在执行以下代码之前先备份数据库

分贝/迁移/ 001_safeguard_create_database.rb

class SafeguardCreateDatabase < ActiveRecord::Migration
  def up
    # if current migration version already has a created database
    if ActiveRecord::Migrator.current_version > 2
      # force the next migration 002_create_database.rb to be skipped
      ActiveRecord::SchemaMigration.create(version: '2')
      # the version '2' above is the version of the file which is (002 becomes 2)
    end
  end
  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

分贝/迁移/ 002_create_database.rb

class CreateDatabase < ActiveRecord::Migration
  def up
    # your schema.rb here
  end
  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

创建这两个文件后,请尝试rake db:migrate。它应该只处理001_safeguard_create_database,并跳过002_create_database,因为假设您当前的数据库已经设置了它。然后只会为没有数据库的新项目用户运行002_create_database;对于这些用户,首先运行前两个迁移文件,然后运行所有其他迁移。

答案 1 :(得分:1)

我遇到了同样的问题,但我无法使用上述解决方案。

我的数据库之前是创建的,而不是ruby on rails应用程序,并且它没有创建schema_migrations表,所以当它运行时:

if ActiveRecord::Migrator.current_version > 2
    # force the next migration 002_create_database.rb to be skipped

    ActiveRecord::SchemaMigration.create(version: '2')

    # the version '2' above is the version of the file which is (002 becomes 2)
end

它在if语句中返回false,因此在我的情况下它永远不会跳过create_database迁移。

我一直在寻找可以运行迁移的方法,并避免再次创建表,同时,新的编码器可以运行它并创建表。

经过一些搜索,我找到了table_exists?函数,所以:

  1. 我使用rake db:schema:dump
  2. 创建了架构迁移
  3. 然后我创建了我的第一次迁移:001_create_database.rb并粘贴了db/schema.rb文件中的架构
  4. 最后,我在每个创建表之前编辑了迁移添加和if语句:

    if !table_exists?("CarsTable")
        create_table "CarsTable" do |t|
            t.bigint   "Owner", null: false
            t.string   "Color", limit: 20, null: false
            t.string   "Make",  limit: 40, null: false
            t.string   "Model", limit: 20, null: false
            t.string   "Plate", limit: 10, null: false
         end
    end
    
  5. 我以两种方式对此进行了测试,先前创建并填充了数据库(对于生产案例和我自己的案例)并且没有任何数据库(对于新编码器)并且它有效。