A question you’ll occasionally see: when do you run your migrations in
production? There’s a standard answer, so let’s talk about it.
You’ll run your migrations before you deploy new code. In general,
that means “every time you push code to production, you run all the
migrations since the last time you pushed code to production. Do it
before you replace the old code.”
Easy enough. Why?
First, because that’s the order you think about things. If you’re
adding a new column to a table, you’ll want to make your code use
it. If you run the migration first, that all works out nicely.
It doesn’t work for dropped columns, but that’s why dropping a column
can be a little tricky.
Running the migration afterwards is possible, but usually
annoying. If it takes two (or more) migrations to drop a column, well,
you weren’t using that column anyway. If it takes two migrations to
add a column, you’re very sad that you’ll have to wait a deploy
(a day? a week? a month?) before you can add that new feature.
Second, it makes it clear when to do it. If you’re deploying to a
cluster of four or five app servers, you don’t want to have to turn
them all on a dime from the old code to the new code. Realistically,
there’s going to be a bit of “gray area” between the old and new code
when not everything has switched over. So you should assume you’re
going to have both the old and new code running at once. So the only
safe times to run the deploy are before all of that, or after
all of it.
And “after”, again, has some problems.
Why Not Both?
Technically you could have some kind of “pre-deploy migrations” and
“post-deploy migrations” be separate. But the more steps you add, the
more complex you’re likely to find your deployment… and
rollback. What do you do if the pre-deploy migration succeeds and the
post-deploy migration fails? Do you have separate rollbacks for each?
Or do a rollback even though things “basically worked?” It’s possible,
but… well, better you than me. In general, try to simplify. Having
multiple separately-reversible stages of migrations isn’t likely to be
the simplest solution.
Most tools will just choose this for you. If you’re running Capistrano, say, it will quietly do
the right thing without fussing over it. So if you expect the right
thing, everything will “just work.”
Now you can expect the right thing, because you know what it is. And
in one more situation, everything will quietly just work because you
knew how to write your migrations.