ruby-on-rails - 我可以重建 db/schema.rb 以包含多个数据库而无需迁移吗?

标签 ruby-on-rails database postgresql database-schema schema.rb

我有一个 Rails 5 应用程序,它使用三个不同的现有数据库。此应用程序不需要迁移。我想构建 db/schema.rb 以包含所有三个数据库,而不仅仅是主数据库。执行 rake db:schema:dump 使用主数据库重建模式。我相信有一种方法可以做到这一点,但由于某种原因,我一直在搜索的方式我找不到任何关于此的信息。我找到的所有帖子都讨论了如何使用来自不同数据库的模型,而不是如何重建架构以包含所有数据库。

最佳答案

大约一个月前我又开始看这个了。在审查了几个选项后,我发现了一个由@ostinelli 创建的解决方案,它运行良好且易于实现。该解决方案为每个维护的数据库创建单独的迁移,而不是将它们全部放在一个模式文件中。我的目标主要是为每个数据库创建一个模式,这为我完成了。有些部分我没有实现,因为它们不需要。

http://www.ostinelli.net/setting-multiple-databases-rails-definitive-guide/

我为每个数据库创建了单独的数据库 yml 文件,如下所示:

config/database_stats.yml

development:
  adapter: postgresql
  encoding: utf8
  host: localhost
  pool: 10
  database: myapp_stats_development
  username: postgres
  password:

test:
  adapter: postgresql
  encoding: utf8
  host: localhost
  pool: 10
  database: myapp_stats_test
  username: postgres
  password:

production:
  adapter: postgresql
  encoding: utf8
  url:  <%= ENV["DATABASE_STATS_URL"] %>
  pool: <%= ENV["DB_POOL"] || 5 %>

然后我为每个数据库创建了单独的数据库 rake 任务:

lib/tasks/db_stats.rake

task spec: ["stats:db:test:prepare"]

namespace :stats do

  namespace :db do |ns|

    task :drop do
      Rake::Task["db:drop"].invoke
    end

    task :create do
      Rake::Task["db:create"].invoke
    end

    task :setup do
      Rake::Task["db:setup"].invoke
    end

    task :migrate do
      Rake::Task["db:migrate"].invoke
    end

    task :rollback do
      Rake::Task["db:rollback"].invoke
    end

    task :seed do
      Rake::Task["db:seed"].invoke
    end

    task :version do
      Rake::Task["db:version"].invoke
    end

    namespace :schema do
      task :load do
        Rake::Task["db:schema:load"].invoke
      end

      task :dump do
        Rake::Task["db:schema:dump"].invoke
      end
    end

    namespace :test do
      task :prepare do
        Rake::Task["db:test:prepare"].invoke
      end
    end

    # append and prepend proper tasks to all the tasks defined here above
    ns.tasks.each do |task|
      task.enhance ["stats:set_custom_config"] do
        Rake::Task["stats:revert_to_original_config"].invoke
      end
    end
  end

  task :set_custom_config do
    # save current vars
    @original_config = {
      env_schema: ENV['SCHEMA'],
      config: Rails.application.config.dup
    }

    # set config variables for custom database
    ENV['SCHEMA'] = "db_stats/schema.rb"
    Rails.application.config.paths['db'] = ["db_stats"]
    Rails.application.config.paths['db/migrate'] = ["db_stats/migrate"]
    Rails.application.config.paths['db/seeds'] = ["db_stats/seeds.rb"]
    Rails.application.config.paths['config/database'] = ["config/database_stats.yml"]
  end

  task :revert_to_original_config do
    # reset config variables to original values
    ENV['SCHEMA'] = @original_config[:env_schema]
    Rails.application.config = @original_config[:config]
  end
end

然后我为其他数据库创建了自定义迁移生成器。

lib/generators/stats_migration_generator.rb

require 'rails/generators/active_record/migration/migration_generator'

class StatsMigrationGenerator < ActiveRecord::Generators::MigrationGenerator
  source_root File.join(File.dirname(ActiveRecord::Generators::MigrationGenerator.instance_method(:create_migration_file).source_location.first), "templates")

  def create_migration_file
    set_local_assigns!
    validate_file_name!
    migration_template @migration_template, "db_stats/migrate/#{file_name}.rb"
  end
end

我为每个数据库创建的数据库迁移类似于:

rails g stats_migration create_clicks
create db_stats/migrate/20151201191642_create_clicks.rb
rake stats:db:create
rake stats:db:migrate

然后为其他数据库创建单独的数据库初始化程序,然后修改每个模型。

config/initializers/db_stats.rb

DB_STATS = YAML::load(ERB.new(File.read(Rails.root.join("config","database_stats.yml"))).result)[Rails.env]

class Click < ActiveRecord::Base
  establish_connection DB_STATS

end

当我第一次写这个问题时,我的应用程序中有三个数据库。我现在正在添加另一个数据库。我很感激@ostinelli 写了这篇文章。它让我的生活更轻松。

关于ruby-on-rails - 我可以重建 db/schema.rb 以包含多个数据库而无需迁移吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40119912/

相关文章:

database - 哪些服务器是公共(public)的和私有(private)的 哪些服务器被使用 它是如何工作的

PostgreSQL 消耗大量内存用于持久连接

SQL 计数器困难

ruby-on-rails - 删除文件后 development.log 不记录

ruby-on-rails - 使用 Elasticsearch/Tire 通过时间表查找开放商店

ruby-on-rails - 如何在 rails json 响应中合并对象中的另一个字段

ruby-on-rails - 如何管理具有不同数据库模式的 git 分支?

java - MyBatis 字符串作为参数

multithreading - 对于从作业队列中拉出运行的工作人员,我应该使用什么隔离级别?

ruby-on-rails - 在 Rails 项目中设置 Shoryuken、Active Job 和 Amazon SQS