Edited at

複数のDBに対するマイグレーションのあれこれ

More than 1 year has passed since last update.

railsで複数のデータベースを使いたい時がある。

そんな時は@eagletmtさんが作成したswitch_pointを使うと良い感じになれる。

使い方などはGitHubのドキュメントを見れば何も困らない。

本題はこっから

例えばメインをmysqlにして2つ目をpostgresqlなどにした場合にpostgresql側のマイグレーションどうしようってなる。

ちなみにdatabase.ymlはこんな感じ


database.yml

・・・

development_postgresql:
adapter: postgresql
host: localhost
database: hogehoge
username: postgres
password:
pool: 5
timeout: 5000


シンプルなパターン

どちらもスキーマが一緒でmigrationの設定などを共有して使用する時


完成系

$ RAILS_ENV=development_postgresql rake db:create

$ RAILS_ENV=development_postgresql rake db:migrate


解説



  • rake db:createを定義している所を見てみるActiveRecord::Tasks::DatabaseTasks.create_currentってのを呼んでるっぽい


  • ActiveRecord::Tasks::DatabaseTasks.create_currentの呼び出し元はここ

  • そして一番のポイントとなるのがここ


    • ここでRAILS_ENVに応じたdatabase.ymlの設定を呼んでるっぽい




ちょっとややこしいパターン

ことなるスキーマでマイグレーションファイルも違うのを使用したい時など

ちょっとややこしいことをする時はtaskを書いてあげる。


完成系


psql.rake

namespace :psql do

DEFAULT_DB_CONF = 'development_postgresql'
DEFAULT_ENV = 'development'

task :load_config do
db_conf = ENV['PSQL_DB_CONF'] ||= DEFAULT_DB_CONF
env = ENV['RAILS_ENV'] ||= DEFAULT_ENV
ActiveRecord::Base.configurations = {env => ActiveRecord::Base.configurations[db_conf]}

# migrationを変えたいときはこれに代入する。 default: [db/migrate]
# ActiveRecord::Migrator.migrations_paths = ["#{Rails.root}/db/hoge_migrate"]
end

# データベース作成
task create_db: :load_config do
ActiveRecord::Tasks::DatabaseTasks.create_current
end

# マイグレーション
task migrate: [:environment, :load_config] do
ActiveRecord::Tasks::DatabaseTasks.migrate
end

end



解説

参考にするのはrake db:createなどを呼び出した時に呼ばれるdatabases.rake

メインはload_configタスク。

動きとしてはdb_confにdatabase.ymlのどの設定を取り出すかを指定。

後はRAILS_ENVに応じて設定が読まれるのでdatabase.ymlのhashをRAILS_ENVに応じて作成してActiveRecord::Base.configurationsにいれるだけ。

よく「rails 複数のDB migrate」と検索するとRails.application.config.pathsにschemaの場所とかdatabase.ymlの場所を指定してるけど、今回switch_pointで1つのdatabase.ymlにいれているので、ymlファイルをわけたくなかったため、こんな実装になっている。

最適な解ではないかもしれないけど。。。


やってみて

とりあえずドキュメント読めばなんとかなる。

ただとりあえずなのでRails Wayに乗れていない感があるのでもっとスマートなやり方があったら教えてほしい