如何在Rails中阻止db:migrate执行子文件夹内的迁移?
多站点独立数据库的迁移方案分享
我最近搞定了一个多站点架构下的数据库迁移需求——每个站点有自己的独立数据库,同时还有一个主数据库存储站点列表。下面是我整理的目录结构和自定义Rake任务实现:
迁移文件目录结构
我把迁移文件分成了全局主库迁移和站点独立迁移两个部分,结构清晰明了:
db/ └── migrate/ ├── 20240520120000_create_sites.rb # 主数据库的迁移:创建站点列表等全局表 └── site/ # 存放仅在站点独立数据库运行的迁移文件 └── 20240520130000_create_users.rb # 每个站点专属的用户表迁移
db/migrate/根目录下的文件:只在主数据库执行,用来维护所有站点共用的数据表db/migrate/site/子目录下的文件:仅在对应站点的独立数据库中执行,比如每个站点自己的用户、内容表等
自定义Rake任务实现
为了批量处理所有站点的独立数据库迁移,我写了一个db:sites Rake任务,已经测试可用。完整代码如下:
desc "Migrate the database through scripts in db/migrate/site." namespace :db do task :sites => :environment do @sites = Site.all @sites.each do |site| # 复制当前连接配置,替换为站点专属数据库名 conn_config = ActiveRecord::Base.connection_config.dup conn_config[:database] = site.id.to_s # 这里假设站点ID就是对应的数据库名,可根据实际业务调整 # 切换到当前站点的独立数据库 ActiveRecord::Base.establish_connection(conn_config) # 执行site目录下的迁移(支持指定版本回滚) target_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil ActiveRecord::Migrator.migrate("db/migrate/site/", target_version) # 切回主数据库连接,避免影响后续操作 ActiveRecord::Base.establish_connection(Rails.env.to_sym) end end end
使用说明
- 批量执行所有站点的迁移:在终端运行
rake db:sites - 回滚到指定版本:运行
rake db:sites VERSION=20240520130000(替换为对应的迁移版本号) - 注意事项:要确保每个站点的独立数据库已经提前创建完成,否则会抛出数据库连接错误
内容的提问来源于stack exchange,提问作者Rando Hinn
相关产品推荐
相关产品推荐

