We had the similar problems: too many DB migrations script resulted slow tests execution. On top of this we have pretty complex environment to run the application: all tests are running against empty docker DB, we have several deployments with different DB versions (dev - latest, stage - some, prod - oldest).
There are two cases: when you have all versions in dev/stage/prod aligned and when dev/stage is ahead of prod. Below I'll describe resolution for the case when you have the same DB version on all environments.
The second case is also possible to resolve but it requires more efforts to implement. General approach - merge DB schema up to "oldest" DB version, rename newest migration scripts to new versions after major one and make sure newest DB changes will no apply twice (check if changes already applied or not).
"All envs DB version aligned" steps:
- Create "merged" DB script. You can run your project against empty DB and extract schema from there using your DB type specific tools.
- Delete (or move) all DB migration script files from the configured flyway location and replace with generated file in the previous step. I suggest to create new major version, so if you have latest V1_300, merged file will have V2_0
- Create beforeValidate.sql (see flyway docs) in the same as V2_0 script location with the content (example for MSSQL/AzureSQL):
-- run baseline manually
if OBJECT_ID(SCHEMA_NAME() + '.flyway_schema_history', 'U') IS NOT NULL
if exists(select 1
from flyway_schema_history
where version = 'YOU_FIRST_MIGRATION_VERSION_AFTER_BASELINE')
begin
begin
declare @max_inst_rank int;
select @max_inst_rank = MAX(installed_rank) from flyway_schema_history;
delete from flyway_schema_history;
INSERT INTO flyway_schema_history (installed_rank, version, description, type, script, checksum,
installed_by,
installed_on, execution_time, success)
VALUES (@max_inst_rank + 1, 'YOUR_MERGED_VERSION', '<< Flyway Baseline >>', 'BASELINE', '<< Flyway Baseline >>', NULL,
'WHO_CREATED', GETDATE(), 0, 1);
end;
end;
GO
Where:
YOU_FIRST_MIGRATION_VERSION_AFTER_BASELINE - number of first migration after baseline, for example 1.0.1
YOUR_MERGED_VERSION - number of new "merged" version, for example 2.0.0
WHO_CREATED - person who created the record
This script will run BEFORE flyway validates migration DB records against migration files, so it will do:
- when flyway_schema_history is not exists (we are running on empty DB)- dong nothing
- when flyway_schema_history exists
- and first migration (1.0.1 for example) exists - delete all records
in flyway_schema_history and create new baseline out of "merged" and
set version to 2.0.0. No actual DB changes will be done since it is already there.
- and first migration 1.0.1 do not exists - do nothing since we already did all necessary actions.
At the end of all this actions and deployment to all environments you'll have V2.0.0 file and one BASELINE record in flyway_schema_history table.
You can proceed to create new DB mitigation scripts starting with version V2.0.1
You can also move flyway_schema_history table records to another table instead of delete for audit purposes.
beforeValidate.sql script will run at each server start and, in general, do nothing since all changes already applied. You can remove the script from flyway folder when al environments upgraded.
Validated on flyway 8.5.x, SpringBoot 2.7.x