2011-10-04 62 views
2

我的应用程序依赖于已经在数据库中存在大约48,000行数据(MySql)。在我看来,通过ActiveRecord抽象,这会产生一个问题,即每次发生迁移时都必须重新插入此数据。这确实是这样吗?还是有解决方法?Rails:如何使用数据填充Db而无需迁移?

回答

1

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 

要填充它,您需要创建一个迁移,以充当您的首选数据接口和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 

谨慎

的话,我会提醒你,虽然你可能在一个长途(至少一两天)。我已经对完全不同平台上运行的旧应用程序的数据进行了肮脏的迁移,并且您最好希望您的数据集是完美的(并且您已经完全模拟了数据模型),或者将会中断。

此外,可能的监督

在情况下,我误解你的问题,你正在寻找预填充用随机数据的数据库,你应该在Forgeryrandom-data,和/或Faker偷看。

如果我在这里完全是偏离点,随时发表评论,我会相应地调整我的答案。

1

在rails中,迁移是对您的数据库模式执行(通常是可逆)修改的代码。迁移示例是将一列或多列添加到表中,更改列的名称或添加整个表。它类似于运行SQL命令来执行相同的操作 - 它不会删除表并重新生成它。

运行迁移时在数据库中有数据实际上是一个非常正常的情况。