rc3.org

Strong opinions, weakly held

Managing Rails migrations

I’ve mentioned Rails migrations in the past. They provide a way to script database schema changes so that you can keep them in version control and roll back versions of a schema if necessary. One thing about them though is that eventually your list of migrations gets huge. (We’re up to over 20 of them in some of our applications, and there’s no reason why we might not have over 100 some day.)

The question becomes, when do you delete all of your migrations and start over with a fresh schema? It seems to me that eventually it comes time to create a fresh database, run all of your migrations on it, and then export that database to a new file and then delete all of your migrations and call that new file migration #1.

My feeling is that this is a function of application versioning. When you reach a big milestone (the kind you wouldn’t want to roll back from incrementally), it’s time to bundle up all your migrations. Unfortunately, that seems like it would conflict with maintaining an existing application. The schema version is stored in the database for live applications, and if you reset the number you lose the ability to run subsequent migrations against an existing database.

Anyone know if there’s a plan for how to handle this sort of thing in the Rails world that I’m missing? The reason I ask is that we have applications that we’re planning on releasing as open source. They also have live instances that are currently running. For the sake of those applications, it seems logical to never roll up the migrations. Distributing an open source application that has to run 50 migrations to get the database set up seems like a bad plan, though. You could distribute your application with a schema import file, but then when you release subsequent versions, you lose the ability to distribute a migration with them that automatically updates the user’s database.

I guess I need to do some research.

7 Comments

  1. Rails Migrations Gone Wild

    Rafe Colburn wonders when you should clean up your Rails migrations: The question becomes, when do you delete all of your migrations and start over with a fresh schema? It seems to me that eventually it comes time to create a fresh database, run all of yo

  2. Why not use the suggested subversion branch/tag/trunk directory tree?

    \myapp
    +-\trunk
    +-\branch
    |   +-\b01
    |   +-\b02
    |   +-...
    +-\tag
    +-\v-2.1
    +-\v-2.3
    +-\v-2.5
    +-...
    

    So, all main development goes on in the trunk, and the past releases are maintained under their own directories. Any global updates are merged across versions + trunk.

    See Branching and Merging in the subversion book (pp 61-85 in Svn 1.2 rev 2147) for details.

  3. Branching and merging only complicate the problems with migrations. What happens when I make migration #9 in the trunk and you make migration #9 in the development branch? How do we merge the two cleanly?

  4. We typically use branches for items that will break the trunk until they’re fully implemented. The rule is the trunk can never break – it must always compile and be functional.

    Small changes are made to the trunk, but larger changes are branched, and then remerged when complete.

    If I understand you correctly, Developer A is working on the trunk and B is working on a branch. They both make changes and you want to know how to incorporate them cleanly.

    When B is ready to move her branch back to the trunk, she first does a refresh from the trunk to ensure that anything new is now in her branch. She tests and verifies that everything works, then merges the branch into the trunk (probably testing a final time).

    Meanwhile, A is working on the trunk, so just before he commits, he does a refresh; all the new stuff that B added is then added to his local copy. He runs his tests and when they come out clean, he commits.

    If I recall correctly, if A tries to commit without refreshing, subversion will give a warning that his copy is not up to date and then fail the commit, preventing accedental overwriting of changed objects. I haven’t run into this in a long time because my projects for the last few years have consisted of a development team of 1 (me). 😛

  5. Actually what I’m talking about is something completely different — Rails migrations, which let you version schema changes to a database.

  6. Here is a really, really useful (and pretty!) Rails Migrations cheatsheet in printable PDF format: Rails Migrations cheatsheet

  7. Did you ever find a good solution for this? I couldn’t find any automated method, so came up with this procedure:

    1. rake db:schema:dump
    2. rake db:data:dump (requires yaml_db plugin I believe)
    3. script/generate migration create_schema
    4. copy contents of db/schema.rb into db/migrate/create_schema, editing as necessary (eg. reorder fields, remove :force option, add t.timestamps, change strings to symbols, create drop_table’s for self.down)
    5. delete each of the migrations before the newly created one
    6. rake db:drop
    7. rake db:migrate
    8. rake db:data:load

    Now the database is up to date and all the migrations have been rolled into one.

Leave a Reply

Your email address will not be published.

*

© 2024 rc3.org

Theme by Anders NorenUp ↑