如何为具有多个数据库的Rails创建迁移

3
我发现这个问题非常有趣,我想了解如何生成迁移以在项目中使用的其他数据库中创建表。
我该如何使这样的迁移在第二个数据库中生成表?
class CreateOriginalCompanies < ActiveRecord::Migration
  def change
    create_table :original_companies do |t|
      t.string :CompanyName
      t.string :RegAddress_AddressLine1
      t.string :RegAddress_AddressLine2
      t.string :RegAddress_PostTown
      t.string :RegAddress_Country
      t.string :RegAddress_PostCode
      t.string :CompanyCategory
      t.string :CompanyStatus

      t.timestamps null: false
    end
  end
end

任何线索?
1个回答

13

Rake任务

让我们直接开始。显然,我们想要为两个数据库处理迁移,因此我们需要两个单独的Rake任务来处理:

desc "Migrate the database through scripts in db/migrate."
namespace :db do
  task :migrate do
    Rake::Task["db:migrate_db1"].invoke
    Rake::Task["db:migrate_db2"].invoke
  end

  task :migrate_db1 do
    ActiveRecord::Base.establish_connection DB1_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db1/")
  end

  task :migrate_db2 do
    ActiveRecord::Base.establish_connection DB2_CONF
    ActiveRecord::Migrator.migrate("db/migrate/db2/")
  end
end

我们的第一个任务是db:migrate,它委托给db:migrate_db1db:migrate_db2

每个都建立到数据库的连接,然后从它们自己的单独文件夹运行迁移。这使您可以将迁移存储在单独的文件夹中,以便轻松管理它们。

您的迁移与普通迁移完全相同。

数据库连接

为了使这些迁移工作,我们需要配置数据库连接。我们将像平常一样在database.yml中定义所有内容,但使用不同的命名约定:

db1:
  development:
    adapter: mysql2
    database: db1_dev
    username: root

  test:
    adapter: mysql2
    database: db1_test
    username: root

  production:
    adapter: mysql2
    database: db1_prod
    username: root


db2:
  development:
    adapter: mysql2
    database: db2_dev
    username: root

  test:
    adapter: mysql2
    database: db2_test
    username: root

  production:
    adapter: mysql2
    database: db2_prod
    username: root

在这里,我们正在配置两个独立的数据库 db1db2

现在我们需要配置我们的应用程序来加载它们。我通常会在 boot.rb 中进行此操作,但如果您使用的是 Rails,则可能需要在 application.rb 或环境文件中完成。

ENV['ENV'] ||= 'development'

  db_conf = YAML::load(File.open(File.join(APP_PATH,'config','database.yml')))

  DB1_CONF = db_conf["db1"][ENV['ENV']]
  DB2_CONF = db_conf["db2"][ENV['ENV']]

所以,让我们来看看发生了什么:

  1. 我们设置要使用的数据库配置。Rails用户可以在这里使用Rails.env,而不是ENV['ENV']
  2. 其次,我们加载database.yml配置文件并用YAML解析它
  3. 最后,我们为每个db从文件中获取配置和我们正在运行的正确环境。

连接您的模型

当您使用多个数据库时,我喜欢在模型本身中明确设置连接,而不是继承ActiveRecord :: Base并使用子类。

class Message < ActiveRecord::Base
  establish_connection DB1_CONF
end

而我们在另一个数据库中的第二个模型:

class User < ActiveRecord::Base
  establish_connection DB2_CONF
end

结论

这就是它的简单之处。你只需要加载配置,正确地建立数据库连接,并设置迁移以从每个数据库的特定文件夹加载即可。

我相信有更好的处理方法,如果您有建议,请在评论中告诉我!


谢谢,很好的东西,但我得到了一个 ActiveRecord::AdapterNotSpecified 异常,由 activerecord (4.2.0) lib/active_record/connection_adapters/connection_specification.rb:248:in resolve_symbol_connection'` 引起。 - Don Giulio
4
来源丢失:http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/还有其他人也遇到了同样的问题:http://excid3.com/blog/rails-activerecord-multiple-databases-and-migrations/#comment-985030733 - eXa
通常在项目根目录下的 Rakefile 中,@sriharisairamVentrapragada。 - sudoremo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接