【问题标题】:Can I Rebuild db/schema.rb to Include Multiple Databases Without Migrations?我可以重建 db/schema.rb 以包含多个数据库而不进行迁移吗?
【发布时间】:2017-02-28 09:59:19
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    大约一个月前,我再次开始关注这个问题。在查看了几个选项后,我发现了一个由@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 写了这篇文章。它让我的生活更轻松。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      相关资源
      最近更新 更多