Skip to content

Better support for team development of database migrations #32351

@br3nt

Description

@br3nt

The problematic migration process

How do you rebase or merge a branch containing migrations specifically in the case where the parent branch has new migrations that do not exist in the branch being rebased or merged?

The only fool-proof method I know of is to delete the new migrations in the feature branch, do a rebase onto the parent branch, then recreate the migration with Add-Migration. The main problem with this method is that the developer is forced to squash the migrations into a single migration. There are many situations where multiple migrations are required to correctly modify a database schema and ensure integrity of the data. A developer could instead use interactive rebase; stopping at each commit containing a migration, and running the Remove-Migration then Add-Migration commands. But as you can imagine, this is quite error prone. This gets repetitive and tedious when you need to rebase your branch multiple times.

The impact on development

The currently tooling is insufficient to effectively handle most migration conflicts. It is high risk. This leads to a fear of making database schema changes in parallel, and instead forces database development to occur in serial. This dramatically reduces a development teams ability to move quickly, as features that require database schema changes are delayed until database schema changes already in the pipeline are completed.

This situation is an artefact of the current migration process. It is entirely avoidable and can be resolved by improving the current migration process.

The problem to solve

There are at least three problems that need to be address:

  • the timestamps of the migrations in the feature branch may be earlier than one or more of the timestamps of the migrations in the parent branch
  • the content of DbContextModelSnapshot.cs from the feature and parent branches may have conflicting changes
  • The database objects being modified by a migration in the feature branch may no longer exist in the parent branch

There are probably other scenarios I have not captured.

The proposed solution

I am proposing a new option for managing database migrations that developers can opt into.

The new option should have the following features:

  • migrations are decoupled from timestamps
  • migrations can be rebased on top of the latest migration
  • the DbContextModel is dynamically built from the commands within the migration

E.g:

  • Instead of ordering migrations by the timestamp in the filename, the migration definition will specify the parent migration
    • Preferably, an incrementing index should be used to maintain file ordering rather than a timestamp. This index could also be referenced when performing rollbacks. Much easier than typing a migration name
  • The DbContextModel is built up as the migrations run in order
    • The up/down migration should be the single source of truth for schema changes, so the .Design should also be removed.
    • An error is thrown if a migration modifies the DbContextModel in an undefined way
      • E.g. a column is modified when the column doesn't exist
  • If two or more migrations point to the same parent migration, the migrations need to be rebased
    • The developer can run a command, Rebase-Migration, specifying the migration to be rebased onto the latest parent migration
    • The developer repeats this process until all migrations have a single parent
    • The developer needs to resolve any issues identified when building the DbContextModel
    • After a rebase, it's possible the DbContextModel will be built in an undefined way and throw an error
      • The developer should be given sufficient details so they can modify their rebased migration(s) to complete without errors
    • At each step, the develop can commit the changes into their version control system
  • It is expected that Add-Migration works in the same way as it currently does
    • except no hardcoded DbContextModel is generated

These changes would allow allow multiple developers to merge in their database schema changes with minimal conflicts, and in a way that is compatible with version control systems.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions