我的应用程序依赖于数据库 (MySql) 中已有的大约 48,000 行数据。在我看来,使用 ActiveRecord 抽象会带来这样的问题:每次发生迁移时都必须重新插入此数据。情况确实如此吗?或者有解决办法吗?
最佳答案
Ruby on Rails 通过以不同的方式跟踪对应用程序架构所做的更改来处理迁移。这样做的目的是提供一种非常受控的机制来管理数据库的模式和数据。通过在创建初始数据库架构后使用迁移来预填充数据库,此迁移将仅在每个应用程序部署中执行一次。
也许一个示例是说明如何处理 Rails ActiveRecord::Migrations
的最佳方式。您的时间戳显然会有所不同,因此如果您遇到困难,最好手动尝试一下。
$ rails new example -d mysql
$ cd example/
$ rails generate scaffold Users username:string password:string
invoke active_record
create db/migrate/20111004022310_create_users.rb
create app/models/user.rb
...
...
此迁移创建一个表users
,其中包含两个字符串字段 - 用户名和密码。很简单。现在,在此示例中,我假设您已经预先配置了 database.yml
。
创建数据库、加载架构和初始迁移
$ rake db:setup
/Sites/example/db/schema.rb doesn't exist yet. Run
"rake db:migrate" to create it then try again. If
you do not intend to use a database, you should
instead alter /Sites/example/config/application.rb
to limit the frameworks that will be loaded
我们仍然需要将初始迁移合并到架构中。这会将用户模型的初始规范加载到数据库架构中,然后可以设置数据库。
$ rake db:migrate
== CreateUsers: migrating ====================================================
-- create_table(:users)
-> 0.2389s
== CreateUsers: migrated (0.2390s) ===========================================
$ rake db:setup
-- create_table("users", {:force=>true})
-> 0.1460s
-- initialize_schema_migrations_table()
-> 0.5908s
-- assume_migrated_upto_version(20111004022310, "db/migrate")
-> 0.0010s
此时,您可以轻松进入rails console
并查看初始配置。
$ rails console
ruby-1.9.2-p180 :007 > u = User.new(:username => 'test', :password => 'testing?')
=> #<User id: nil, username: "test", password: "testing?", created_at: nil, updated_at: nil>
ruby-1.9.2-p180 :008 > u.save!
=> true
ruby-1.9.2-p180 :009 > User.all
=> [#<User id: 2, username: "test", password: "testing?", created_at: "2011-10-04 02:33:56", updated_at: "2011-10-04 02:33:56">]
预填充数据库
这样您就可以看到初始用户迁移的样子。
$ cat db/migrate/20111004022310_create_users.rb
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :username
t.string :password
t.timestamps
end
end
def self.down
drop_table :users
end
end
要填充它,您需要创建一个迁移来充当您的首选数据接口(interface)和 ActiveRecord 之间的代理。如果它位于数据库中的某个位置,我建议使用 FasterCSV 之类的工具将其导入到新迁移的 self.up
(或 up
)部分。此迁移只会在每个应用程序部署中执行一次,除非您删除数据库并重新开始。
$ rails generate migration prepopulate_users
invoke active_record
create db/migrate/20111004024648_prepopulate_users.rb
$ cat db/migrate/20111004024648_prepopulate_users.rb
class PrepopulateUsers < ActiveRecord::Migration
def self.up
# Assuming the 'results' is set up as an Enumerable for your data
results.each do |row|
u = User.new( :username => row[:username],
:password => row[:password] )
u.save!
end
end
def self.down
end
end
警告
不过,我要提醒你,你可能会经历很长一段时间(至少一两天)。我已经从运行在完全不同的平台上的旧应用程序中完成了数据的肮脏迁移,您最好希望您的数据集是完美的(并且您已经完美地模仿了数据模型)或者事情将会 中断。
此外,可能存在疏忽
如果我误解了您的问题,并且您希望使用随机数据预填充数据库,您应该看看 Forgery , random-data ,和/或 Faker .
如果我完全偏离主题,请随时发表评论,我会相应地调整我的答案。
关于ruby-on-rails - rails : How to populate Db with data without migrations getting in the way?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7642540/