如何用Rake创建database.yml多数据库?解决仅创建db1的问题
解决Rake创建多数据库的问题
问题根源
你的database.yml结构不符合Rails默认rake db:create:all的预期逻辑。Rails默认的配置规则是以环境(development/test/production)作为顶级节点,每个环境下包含该环境的所有数据库配置;而你现在把数据库名(db1/db2/db3)作为顶级键,这导致默认任务只会识别第一个顶级键(db1)下的数据库配置,所以只创建了db1。
解决方案
下面提供两种可行的解决方式,你可以根据自己的需求选择:
方案1:调整database.yml结构适配Rails默认逻辑
先把配置文件改成环境为顶层的结构,这样rake db:create:all就能正常识别所有数据库:
development: db1: adapter: mysql2 host: 127.0.0.1 database: db1 username: user password: pass db2: adapter: mysql2 host: 127.0.0.1 database: db2 username: user password: pass db3: adapter: mysql2 host: 127.0.0.1 database: db3 username: user password: pass test: db1: adapter: mysql2 host: 127.0.0.1 database: db1_test username: user password: pass db2: adapter: mysql2 host: 127.0.0.1 database: db2_test username: user password: pass db3: adapter: mysql2 host: 127.0.0.1 database: db3_test username: user password: pass
接着需要在Rails配置中注册这些数据库连接,比如在config/application.rb中添加:
module YourAppName class Application < Rails::Application config.after_initialize do # 遍历当前环境下的所有数据库配置并建立连接 config.database_configuration[Rails.env].each do |db_name, db_config| # 跳过主数据库(如果有的话),避免重复连接 next if db_name == 'primary' # 为每个数据库创建独立的连接类 connection_class = Class.new(ActiveRecord::Base) connection_class.establish_connection(db_config) Object.const_set("#{db_name.capitalize}Connection", connection_class) end end end end
完成后,执行以下命令就能创建development环境下的所有数据库:
rake db:create:all RAILS_ENV=development
方案2:自定义Rake任务遍历创建数据库
如果不想修改现有database.yml的结构,可以写一个自定义Rake任务来读取所有顶级键下的数据库配置并创建:
在lib/tasks/databases.rake文件中添加以下代码:
namespace :db do desc "Create all databases defined in database.yml for the current environment" task create_all: :environment do # 加载database.yml配置 db_configs = YAML.load_file(Rails.root.join('config', 'database.yml')) db_configs.each do |db_name, env_configs| # 只处理当前环境的配置 next unless env_configs.key?(Rails.env) current_db_config = env_configs[Rails.env] begin # 建立临时连接并创建数据库 ActiveRecord::Base.establish_connection(current_db_config) ActiveRecord::Base.connection.create_database(current_db_config['database']) puts "✅ Successfully created database: #{current_db_config['database']}" rescue ActiveRecord::StatementInvalid => e puts "ℹ️ Database #{current_db_config['database']} already exists: #{e.message}" end end end end
然后执行自定义任务即可创建所有目标数据库:
rake db:create_all RAILS_ENV=development
内容的提问来源于stack exchange,提问作者agita
相关产品推荐
相关产品推荐

