Reputation: 51
We have a vendor-provided application that is using a MSSQL database as backend. We have multiple instances of this application, and thus multiple databases / databases servers hosting the same database model but with different data.
I'm trying to develop a very simple "browsing tool" to provide a single view of all theses databases (read only).
I'm using Sinatra/ActiveRecord/ActiveRecord-SqlServer-Adapter and I have my models overloaded to comply with the database model.
What I'm now looking for is a way to request all the databases at once and aggregate all the results.
Is there any way to do this in vanilla ActiveRecord? Using a gem?
I found the db-charmer
gem that does something like that, but's it's only compatible with MySQL and I can't get it to work without rails anyway.
Any idea?
Upvotes: 3
Views: 1616
Reputation: 51
I finally found a gem that I was able to hack to do what I need.
I used Octopus
and its sharding capabilities, and I added a simple method to my base controller class (that all my other controllers are based off of) that looks like this:
def on_all_shards(&block)
Octopus.config[:shards].each.collect do |shard, shard_config|
Octopus.using(shard) do
yield
end
end
end
Then in my controllers, whenever I need to aggregate the results of all my shards if just do:
on_all_shards do
Model.first
end
In this case, I would get an array of the first record of this Model/table from each database (1 record / database).
Thank you guys for pointing me to the right direction (ActiveRecord connection/connection_pool management)!
Upvotes: 2
Reputation: 1714
If you had a list of all the connections you could do something like
connection_specs.collect do |spec|
Model.establish_connection(spec)
Model.all
end
or initialize some base classes somewhere
db_klasses = connection_specs.collect do |spec|
Class.new(ActiveRecord::Base) do
establish_connection(spec)
end
end
and then
db_klasses.collect do |db_klass|
db_klass.connection_pool.with_connection do
Model.all
end
end
Upvotes: 1
Reputation: 76784
This won't be a specific answer to your question, but may help you nonetheless
--
Models
We've been working on a multi-tenancy system lately, and needed to access multiple databases
The "way" to do it is actually rather simple - but only if you wanted to do it at model level. Anything else & you've lost me, sorry.
At model level, each time you initialize an instance of an object (IE load a model
), Rails will access the database, and consequently populate the ruby object with the required attributes. A "trick" to making a multi-tenant system (with multiple database connections) is to inherit from different models
Here's an example:
#app/models/option.rb
Class Option < Admin
...
end
#lib/admin.rb
Class Admin < ActiveRecord::Base
self.abstract_class = true
establish_connection "#{Rails.env}_admin"
end
#config/database.yml
production_admin:
your: ____
database: ____
values: ____
This allows you to connect to a different database for your Option
model; providing you with the ability to load the various files / settings to make it work correctly
Whilst I don't think this will address your issue directly (you want to access multiple databases simultaneously), I hope it will give you an idea
--
Database
The bottom line here is that if you want to connect to multiple database simultaneously, you'll likely want to look at identifying the database for the model, and then setting the connection type in the model.
I'm not exactly sure as to whether you're trying to load the data into different model objects, or the same one. If it's through multiple object, you might be able to pull off what I mentioned above, dynamically setting the database as required
--
That's all I've got I'm afraid
Upvotes: 2