alembic revision - multiple heads (due branching) error
Perhaps the most conventional (and robust) solution is to use alembic merge heads
. In the same way that when you have two branches in Git you can bring them back together with a merge commit, in Alembic when you have two branches you can bring them back together with a merge revision.
For instance, suppose we have a revision 1a6b1a4a0574 that adds table A, and a revision 2e49118db057 that adds table B. We can see these revisions (both marked as (head)
) in alembic history
:
$ alembic history
<base> -> 2e49118db057 (head), Add table B
<base> -> 1a6b1a4a0574 (head), Add table A
Then we can merge them by running alembic merge heads
:
$ alembic merge heads
Generating /Users/markamery/alembictest/alembic/versions/409782f4c459_.py ... done
$ alembic history
2e49118db057, 1a6b1a4a0574 -> 409782f4c459 (head) (mergepoint), empty message
<base> -> 2e49118db057, Add table B
<base> -> 1a6b1a4a0574, Add table A
If one of your revisions may have already been run somewhere (including on the development machine of one of your coworkers), then you probably want to use alembic merge
instead of tinkering with the down_revision
of one of the revisions, as the other answers here suggest. The danger of tinkering with the down revision is that it may result in a revision never getting applied. For instance, suppose that your colleague Bob has already pulled down your branch with revision 2e49118db057 and run alembic upgrade head
, creating table B. Then you decide to modify the down_revision
of 2e49118db057 to point to 1a6b1a4a0574, which Bob has never seen or run before. Bob pulls down your change, runs alembic upgrade head
, and... nothing happens, because as far as Alembic is concerned he's already at the head
and doesn't need to run 1a6b1a4a0574. And so Bob ends up never getting table A and probably never figures out why his database is in a broken state.
Don't break Bob's database - make a merge revision instead.
Use the merge
command.
An Alembic merge is a migration file that joins two or more "head" files together. If the two branches we have right now can be said to be a "tree" structure, introducing this merge file will turn it into a "diamond" structure:
-- ae1027a6acf -->
/ \
<base> --> 1975ea83b712 --> --> mergepoint
\ /
-- 27c6a30d7c24 -->
Hence;
$ alembic merge -m "merge ae1 and 27c" ae1027 27c6a
Generating /path/to/foo/versions/53fffde5ad5_merge_ae1_and_27c.py ... done
If you prefer using command
:
>>> from alembic.config import Config
>>> from alembic import command
>>> alembic_cfg = Config("path to alembic.ini")
>>> command.merge(alembic_cfg, revisions=["27c6a30d7c24", "ae1027a6acf"], message="Merge 27c6a30d7c24 and ae1027a6acf")
Reference
- Working with Branches
- See section on resolving without merge
I've run
$ python manage.py db history
And as a result I got
vagrant@precise64:/vagrant$ python manage.py db history
Rev: 29c319804087 (head)
Parent: 313837798149
Path: migrations/versions/29c319804087_.py
empty message
Revision ID: 29c319804087
Revises: 313837798149
Create Date: 2014-03-05 21:26:32.538027
Rev: 313837798149
Parent: 280061454d2a
Path: migrations/versions/313837798149_.py
empty message
Revision ID: 313837798149
Revises: 280061454d2a
Create Date: 2014-01-10 03:19:39.838932
Rev: 280061454d2a
Parent: None
Path: migrations/versions/280061454d2a_.py
empty message
Revision ID: 280061454d2a
Revises: None
Create Date: 2013-12-08 03:04:55.885033
Rev: 2e74f61d3b80 (head)
Parent: 49501407aec9
Path: migrations/versions/2e74f61d3b80_o2_lease.py
o2 lease
Revision ID: 2e74f61d3b80
Revises: 49501407aec9
Create Date: 2014-02-28 10:38:06.187420
Rev: 49501407aec9
Parent: None
Path: migrations/versions/49501407aec9_.py
empty message
Revision ID: 49501407aec9
Revises: None
Create Date: 2014-01-22 11:27:08.002187
What you can see here is 2 different branches. One starts from 49501407aec9 and second from 280061454d2a. I moved 49501407aec9 and the following 2e74f61d3b80 out of the /versions directory, run
$ python manage.py db revision
and it created a new migration file.
This issue happens when two alembic migrations are branched from the same migration. Usually, this happens when multiple people are making schema changes. To fix it you just have to adjust thedown_revision
of your migration to be that of the latest one. Running alembic history
shows us this:
2f4682466279 -> f34e92e9dc54 (head), Fifth revision (on a separate branch)
2f4682466279 -> f673ac37b34a (head), Fifth revision (local)
2dc9337c3987 -> 2f4682466279, Fourth revision
0fa2aed0866a -> 2dc9337c3987, Third revision
22af4a75cf06 -> 0fa2aed0866a, Second revision
9a8942e953eb -> 22af4a75cf06, First revision
You can see that one of the Fifth revisions was made locally and it's downstream revision is2f4682466279
but whoever made the other Fifth revision got the same downstream revision too.
Go into one of the Fifth revision files and update down_revision
variable to reference the other Fifth revision, like this:
f673ac37b34a -> f34e92e9dc54 (head), Fifth revision (on a separate branch)
2f4682466279 -> f673ac37b34a, Fifth revision (local)
2dc9337c3987 -> 2f4682466279, Fourth revision
0fa2aed0866a -> 2dc9337c3987, Third revision
22af4a75cf06 -> 0fa2aed0866a, Second revision
9a8942e953eb -> 22af4a75cf06, First revision
In this case I updated migration f34e92e9dc54
to have down_revision='f673ac37b34a'
.