Question

Let's say I've got an app with a bunch of migration files that I'm getting ready to deploy to production for the first time. From what I understand, I have essentially two options to get the db up on the production server:

  • A - Run db:migrate, and have it cycle through all the migrations it hasn't yet run
  • B - Run db:schema:load, and have it build the db from the schema file

I know B is the right choice for fresh deployments, as explained in the schema.rb comments:

# If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).

What I'm wondering is, how does this affect migrations on the production server going forward? For example, if I do the following in order:

  1. Run db:schema:load on new production server.
  2. Change my schema in development and push to production.
  3. Run db:migrate on production server

What will happen? Will it know to use only migrations that are more recent than the db:schema:load action, or will it try to run them all?

Was it helpful?

Solution

Good question. The answer is that only migrations created after the latest db:schema:load event will ever be run.

The schema.rb file has a version stamp associated with it:

ActiveRecord::Schema.define(version: 20130928225041) do ...

When you run db:schema:load, Rails creates a fresh database according to that schema.rb file, and at the same time populates the schema_migrations table with all the migrations whose version number precede that of the schema.

So as far as I can tell Rails is essentially faking all the migrations up until that point, but doesn't actually run them. (I tested this out by generating an empty migration file, calling db:migrate locally, but then inserting an error into the migration file before deploying it to our server. On the server, we ran db:schema:load, and the result was that the bad migration was included in the schema_migrations table as if it had been run, even though it clearly had not.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top