Alembic revision - ошибка нескольких головок (с учетом ветвления)

У меня есть приложение, и я хотел создать новую миграцию для него сегодня. Когда я бегу

$ alembic revision -m "__name__"

Я получил сообщение

Only a single head is supported. The script directory has multiple heads (due branching), which must be resolved by manually editing the revision files to form a linear sequence. 
Run 'alembic branches' to see the divergence(s).

Бег

alembic branches

ничего не дает

Я новичок в Alembic. Над этим приложением работают 2 разработчика, и у нас есть 2 ветки git - master & development (я не уверен, что это как-то связано с этим).

Любая подсказка о чем это?

Ответ 1

Я запустил

$ python manage.py db history

И в результате я получил

[email protected]:/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

Что вы можете видеть здесь, это две разные ветки. Один начинается с 49501407aec9 и второй с 280061454d2a. Я переместил 49501407aec9 и следующий 2e74f61d3b80 из каталога /versions, запустил

$ python manage.py db revision

и он создал новый файл миграции.

Ответ 2

Эта проблема возникает, когда две миграции алембов происходят от одной миграции. Обычно это происходит, когда несколько человек вносят изменения в схему. Чтобы это исправить, вам просто нужно настроить down_revision вашей миграции, чтобы она соответствовала последней. alembic history показывает нам это:

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

Вы можете видеть, что одна из Пятых ревизий была сделана локально, и это нижестоящая ревизия - 2f4682466279 но тот, кто сделал другую пятую ревизию, тоже получил такую же последующую ревизию.

Перейдите в один из файлов пятой ревизии и обновите переменную down_revision для ссылки на другую пятую ревизию, например так:

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

В этом случае я обновил миграцию f34e92e9dc54 чтобы иметь down_revision='f673ac37b34a'.

Ответ 3

Пожалуй, самое обычное (и надежное) решение - это использовать alembic merge heads. Таким же образом, когда у вас есть две ветки в Git, вы можете объединить их вместе с коммитом слияния, в Alembic, когда у вас есть две ветки, вы можете вернуть их вместе с ревизией слияния.

Например, предположим, что у нас есть ревизия 1a6b1a4a0574, которая добавляет таблицу A, и ревизия 2e49118db057, которая добавляет таблицу B. Мы можем видеть эти ревизии (обе помечены как (head)) в alembic history:

$ alembic history
<base> -> 2e49118db057 (head), Add table B
<base> -> 1a6b1a4a0574 (head), Add table A

Затем мы можем объединить их, запустив 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

Если одна из ваших ревизий, возможно, уже была где-то запущена (в том числе на машине разработчика одного из ваших коллег), то вы, вероятно, захотите использовать alembic merge вместо того, чтобы возиться с down_revision одной из ревизий, как предлагают другие ответы здесь, Опасность возиться с понижающей версией состоит в том, что она может привести к тому, что пересмотр не будет применен. Например, предположим, что ваш коллега Боб уже снял ветку с ревизией 2e49118db057 и запустил alembic upgrade head, создав таблицу B. Затем вы решили изменить down_revision 2e49118db057, чтобы он указывал на 1a6b1a4a0574, который Боб никогда раньше не видел и не запускал. Боб снимает ваши изменения, запускает alembic upgrade head, и... ничего не происходит, потому что в отношении Alembic он уже во head и ему не нужно запускать 1a6b1a4a0574. И поэтому Боб никогда не получает таблицу A и, вероятно, никогда не узнает, почему его база данных находится в неисправном состоянии.

Не ломайте базу данных Боба - вместо этого сделайте ревизию слияния.

Ответ 4

Чтобы объединить головы, вы можете создать пустую "миграцию слиянием" через

alembic history | grep '(head)' | cut -d' ' -f3 | xargs alembic merge -m "merging heads"

Это создаст новое зеркальное отражение, в котором обе (или любое другое число) головы будут направлены вниз. В основном было описано здесь: https://blog.jerrycodes.com/multiple-heads-in-alembic-migrations/