我是一名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
但是我看到一些评论说他们丢失了数据,有些人说它有效。我不能冒险从数据库中丢失数据。有人可以给我一些更可靠的解释吗?或者更好的解决方案
答案 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?
函数,所以:
rake db:schema:dump
001_create_database.rb
并粘贴了db/schema.rb
文件中的架构最后,我在每个创建表之前编辑了迁移添加和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
我以两种方式对此进行了测试,先前创建并填充了数据库(对于生产案例和我自己的案例)并且没有任何数据库(对于新编码器)并且它有效。