pythongitsqlalchemyalembicflask-migrate

Work on multiple branches with Flask-Migrate


I'm using Flask-Migrate (Alembic) to manage SQLAlchemy database migrations. I'm working on two different branches with different migrations.

  1. If I switch branches, I get an error that the migration is not found.
  2. If i merge this branches into the parent branch, I need downgrade migration's on both multiple branches and create new one. If I will not, I get migration's conflict error.

How can I do it easier? Maybe another tool that more like Django's migrations, but for Flask?


Solution

  • Alembic requires the chain of migrations to match the database marker for the current migration. If you create and run some migrations on a branch, then switch to another branch, the database is marked as being on a migration that no longer exists.

    To work on multiple branches while using migrations, you'll need to figure out what the latest common migration on the branch you're switching to is, then downgrade to that version first. Then checkout the branch, and run any migrations that are unique to it.

    For example, assume you created two branches off the "dev" branch called "feature1" and "feature2", and each have one new migration since "dev". To switch from "feature1" to "feature2":

    1. Downgrade the migrations added to the branch, in this case 1: flask db downgrade -1.
    2. Checkout the branch: git checkout feature2
    3. Apply any upgrades for the new branch: flask db upgrade

    If you don't want to lose data due to downgrades that remove columns or tables, you'll need to dump and restore the database for each branch instead.


    If you're working on "feature1" and merge it into "dev", you need to update "feature2" so it knows about the new migrations that were merged in. Alembic will support having multiple branches as long as all the migrations are present. Once you merge "feature2", you can generate a merge migration to consolidate the two migration branches back to one.

    1. Merge "feature1" into "dev": git checkout dev, git merge feature1
    2. Switch to "feature2" and merge "dev": git checkout feature2, git merge dev
    3. Run the migrations from "dev" and "feature2": flask db upgrade
    4. Continue working on "feature2".
    5. Merge "feature2" into "dev": git checkout dev, git merge feature2
    6. Find the migration ids that need to be merged: flask db heads
    7. flask db merge id1 id2, substituting the ids from the previous step.
    8. Update to the merge, note that there is only one head: flask db upgrade, flask db heads

    Unfortunately, this is a manual process. Alembic requires the migration chain to match the database marker, and there is currently no way around that. You may be able to write a git hook to help with this, but it's not something that already exists.