3

How does one load a schema into a secondary database? It seems that the ability to set a secondary database connection while maintaining the main ActiveRecord::Base.connection is not supported in Rails.

Domain Definition

We have models using a secondary database. Our primary database is MySQL, the secondary database is PostgreSQL. To use the ActiveRecord documentation's example:

|
+-- Book
|    |
|    +-- ScaryBook
|    +-- GoodBook
+-- Author
+-- BankAccount

Where Book is abstract and uses establish_connection to connect to Postgres.

When dealing with the database, we can either use ActiveRecord::Base.connection or Book.connection.

Schema dump

To wit: Rails database tasks in the schema namespace allow us to dump the schema as so:

ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)

Which would allow me to do the following:

ActiveRecord::SchemaDumper.dump(Book.connection, file)

Problem: Schema Load

However, the load task holds no such ability. It merely evaluates the schema file as a whole:

desc 'Load a schema.rb file into the database'
task :load => :environment do
  file = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
  if File.exists?(file)
    load(file)
  else
    abort %{#{file} doesn't exist yet. Run "rake db:migrate" to create it then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded}
  end
end

Where the schema file runs ActiveRecord::Schema.define without the connection definition. (Noting that the define method runs in the context of "the current connection adapter").

How do I change that "current connection adapter" without doing an ad-hoc ActiveRecord::Base.establish_connection, which is not what I want to do? I essentially want to run ActiveRecord::Schema.define in the context of Book.connection.

Edit: I'll note that I need a programmatic solution outside of running rake tasks, which is why I'm looking within the rake tasks to see what they're actually doing.

JohnMetta
  • 18,782
  • 5
  • 31
  • 57
  • I believe the answer provided in this link may help: [Switching connection on ActiveRecord::Schema][1] [1]: http://stackoverflow.com/questions/4743007/switching-connection-on-activerecordschema – codester Feb 08 '15 at 23:52

2 Answers2

1

How to dump schema:

ActiveRecord::Base.establish_connection "custom_db_#{Rails.env}".to_sym 
File.open Rails.root.join('db/schema_custom_db.rb'), 'w:utf-8' do |file| 
  ActiveRecord::SchemaDumper.dump ActiveRecord::Base.connection, file
end

How to load schema:

ActiveRecord::Tasks::DatabaseTasks.load_schema_current :ruby, Rails.root.join('db/schema_custom_db.rb'), "custom_db_#{Rails.env}"
vano468
  • 13
  • 1
  • 3
0

I've been struggling recently with trying to just use ActiveRecord. I can load migrations and dump schema but when it comes to loading a schema I run into a similar problem and it's not a Rails or Rake one. Just FYI. I know you don't want do this standalone but I'm trying.

Please note see this post: rake db:schema:load vs. migrations

I'm still obsessed with trying to do it on my own without Rails or Rake help so that I gain a better understanding of how ActiveRecord works.

I made a very minimal Rails structure just to generate migrations.

file structure:

Rakefile
Gemfile
/bin
  bundle
  rake
  rails
/config
  application.rb
  boot.rb
  database.yml
  environment.rb
/db
  /migrate
  development.sqlite3
  schema.rb

  bin/rails generate migration CreateSystemSettings

and I get a file 20150207170924_create_system_settings.rb in the db/migrate folder.

  bin/rake db:migrate

== 20150204070000 DropArticles: migrating 
== 20150204070000 DropArticles: migrated (0.0001s)
== 20150207163123 AddPartNumberToProducts: migrating 
== 20150207163123 AddPartNumberToProducts: migrated (0.0000s) 
== 20150207163909 ChangeSystemSettings: migrating 
== 20150207163909 ChangeSystemSettings: migrated (0.0000s) 
== 20150207170924 CreateSystemSettings: migrating 
-- create_table(:system_settings)
-> 0.0085s
== 20150207170924 CreateSystemSettings: migrated (0.0199s) 

so that works

Update pending

Community
  • 1
  • 1
Douglas G. Allen
  • 2,203
  • 21
  • 20