Dynamically create databases?

Is it possible to dynamically create new databases and tables within them with Rails?

Or is that a task best done manually?

I’m creating an application which should allow users to store their own statistics information (which can and probably with time will be a lot).

My initial thought was to give each user their own database to keep their data separate from each other due to the possible large quantity of data each user will have.

Good idea? Bad idea? Other ways to do it?

Yes, and yes.

That sounds fine.

Just be careful not to optimise prematurely (ie… make design decisions with a VIEW to the future, but don’t let that both you too much in the present). Chances are when it comes to architecture and optimisation, Ya Aint Gonna Need It, and when you do, it’ll most likely be different than you think it will be now.

Focus more on the classes in your system than how to efficiently store them at the inception/design stage.

Julian

Thanks for replying, Julian.

Can you point me to any resources that describe how to do it?

I agree that I should not optimize prematurely but what I’m considering is which is easier,

to go with dynamically creating databases from the start or to extract data from the single database to new databases later on?

It’s at least something to keep in the back of my mind.

What do you mean by a large quantity of data? Modern databases can manage vast amounts of data efficiently. It is very rare for the bottlenecks in a system to be where you expect them to be when you start out and it is very likely that you will find that the extra work was a waste of time. Start with a single database and make sure you have good automated test coverage. Then in the unlikely event that you find that you do have split the database then you can refactor the code and the tests will help to ensure that you have not messed anything up.

Colin

Hi,

You shouldn't attempt to do this if you don't already understand enough Ruby / Rails to do it yourself.

So, I suggest sticking with what you *can* do first.

This might sound like a cop out, but there's very good reason. It's very advanced Rails and you really shouldn't attempt something like this until you understand the basics really well IMHO.

Julian

Thanks for posting, I appreciate the feedback.

I’ll start with keeping everything within a single database and take it from there.

You are right Julian in that I am new with RoR and what I’ve asked for is advanced.

I’m still curious though how creating databases dynamically would be done so if it’s explained anywhere I’d love to read it!

Assuming you are using postgresql you might be interested in this railscast (paid)

[http://railscasts.com/episodes/389-multitenancy-with-postgresql](http://railscasts.com/episodes/389-multitenancy-with-postgresql)

Which takes advantage of being able to have multiple schemas in

PostgreSQL.

Be aware though that it will make your initial coding more

complicated and will have knock-on effects for things like testing etc.

Basically, it will do what you want but it will not be free in terms

of development effort.

I echo other statements that this may be premature optimisation,

look at the railscast, give it a try yourself and see if the trade-off is good enough for you.

(If you do not want to pay for railscasts then have a look at this

gem: https://github.com/influitive/apartment)

Okay…

So to do this, you need to understand meta-programming to a degree because that’s what you’re doing.

In normal Rails, you’d create a model as part of the development process, but what you’re doing is creating some code that creates models itself (ie one level of abstraction higher than normal).

The equivalent straight ruby comparison is: (compare 1, with 2, below):

  1. Creating a class (this is normal programming)

class Cat

def hi

puts ‘meow’

end

end

You can then create new Cat objects like this:

furrycat = Cat.new

and make it meow like this:

furrycat.hi

  1. Creating a piece of code that creates a class (this is meta-programming)

a_class = Class.new

hi_method_block = Proc.new{ puts ‘meow’ }

a_class.send(:define_method, :hi, &hi_method_block)

You can then create new “Cat” objects like this:

furrycat = a_class.new

and make it meow like this:

furrycat.hi

We have toyed with creating separate databases for each customer as our combined one is starting to get quite large. In our case, the models will always be the same no matter which database you are connecting to, so there isn't any meta-programming involved. It's just a case of switching databases to the correct one for that customer once they log into the system.

One thing to consider is that shared data needs to go somewhere (sessions, username/passwords etc) as well.

Cheers Simon

That kind of scenario was what I had initially in mind. Everyone has the same models, just not the same database.

Hello!

I know three years have passed, but I am looking to do exactly what you proposed on your first post, so I am interested in knowing if you have managed to so and if you did, how did you do it?

Thanks in advance.

quinta-feira, 4 de Abril de 2013 às 05:24:18 UTC-4, Johan Vauhkonen escreveu:

Faced a similar problem today and thought I’d post my solution. To figure this out I looked through the rails database.rake codebase: rails/databases.rake at main · rails/rails · GitHub

ActiveRecord::Base.configurations[“newdb”] = { “adapter” => ‘mysql2’, “encoding” => ‘utf8’, “reconnect” => false, “database” => ‘newdb’, “pool” => 5, “username” => ‘[username]’, “password” => ‘[password]’, “host” => ‘127.0.0.1’, “port” => 3306, } ActiveRecord::Tasks::DatabaseTasks.env = ‘newdb’ ActiveRecord::Tasks::DatabaseTasks.create # Creates the database, empty. ActiveRecord::Tasks::DatabaseTasks.migrate # Runs migrations against the new empty database.

``