You describe a situation where Alice and Bob create
feature branches from same spot in main,
and then each creates a new alembic DB migration,
leading to an undesirable merge conflict.
It is unclear why the
documented
approach to merging is unsuitable,
but I will just take that as a given.
Perhaps the learning curve is too steep
or the documentation burden is too great
for your environment.
So the input assumptions are:
- Developers create new DB migrations at a "high" rate.
- Merging feature branch to
maintakes a "long" time. - Conflicts are unacceptable.
Our field is Computer Science, where you can always fix a problem by introducing one more layer of abstraction.
Here is one solution. Never create a simple migration. Instead, always create a migration that is developed in these two steps:
- null migration
- migration required by new app feature
In (1.) Alice creates a null feature branch
where alembic advances from hash1 to hash2
while making zero changes to the database.
Now she has allocated hash1 for her own use,
and leaves hash2 for other developers such as Bob.
This trivial change can be immediately
merged down to main, where it is visible to others.
Even an organization that is heavy on ceremony
would be able to devise a process for low latency
merging of null updates.
Think of the alembic hashes as a linked list,
and Alice reserves the right to later insert
a migration at the site of an "empty" link.
Alice now creates the "real" feature branch,
and proceeds to author app changes plus a
migration from hash1 -> hash2.
Bob meanwhile does something similar so
main has hash3, and he proceeds to author
a hash2 -> hash3 migration.
Either Alice or Bob will win the race,
when their feature is finished and they merge to main.
The other developer will need to exercise some care to verify the final migrations do not conflict. Ideally this would have been worked out during Sprint Planning, but by hypothesis the OP suggests the organization has yet to converge on a means of deconflicting early in the process. So we should test migrations that go backward "far enough" and then bring us up-to-date.
Suppose Alice won the race.
When Bob is about to merge down to main,
he already knows that tests run fine with Alice's null migration.
He pulls her code, verifies that her actual migration
also integrates fine, and at last merges his feature branch.
Alternatively Bob won the race. When Alice is ready to merge to main, she pulls his code and verifies her feature doesn't break it.
In general there could be N racing feature branches, which implies that on each merge a test should go back at least N migrations to verify that things still work.