Complete Guide to Database Migrations with Flyway and Spring Boot

Database Migrations with Flyway  and Spring Boot

In this blog post , I’ll show you how to use Flyway database migrations with Spring Boot. I’ll walk you through the process of setting up Flyway, creating migrations, and migrating your database.

What is Database Migration ?

Let’s say that we’re developing a web application that’s going to use a Postgres database. If we were to build our application from scratch, we’d probably start with a blank database and then add the tables and data we need. We’d probably also add a few useful SQL scripts to create the database and set up the schema.

Your Application Builds Great, but You’re Running The Application On your local development machine. You need to document all the changes done during development to your local database and apply same changes in integration, pre production and production environments.

Typically there would be team of developers working on the project and making changes to their own local databases.

As more then one member is working on database changes ,we now not only have to deal with one copy of our environment, but with several. This presents a number of challenges.

Actually we face similar issue with code changes, but on the programming side, we’ve done quite well at solving problems using

  • Version Control Systems
  • Reproducible builds and continuous integration
  • Streamlined release and deployment processes

When it comes to database changes, well unfortunately we have not been doing so well there. Many projects still rely on manually applied sql scripts.

This leads to many questions in real world.

  • What is the current condition of the database on given machine?
  • Is this script already in applied or not?
  • Has the quick fix in production been applied in other environments afterwards?
  • How do you create a new database instance?

Most of the times the response to these queries is: We don’t know.

Database migrations are a great way to regain control of this situation.

They allow you to:

  • Rebuild a database structure from scratch
  • Easily check at all times what state a database is in
  • Deterministically transition from your existing database version to a newer one.

What is Flyway ?

Migrating a database can be a daunting task. It can be difficult to track all the changes that have been made to a database over time, and making changes to a database without proper planning can lead to data loss or corruption. Fortunately, there is a tool that can make database migration easier and less risky.

Flyway is a tool that helps you track and manage database migrations. It allows you to easily migrate your database from one version to another, and it helps you avoid the risk of data loss or corruption.

How Flyway Works

When you point Flyway to an empty database. It will try to locate its schema history table.

As the database is empty, Flyway won’t find it and will create it instead. You now have a database with a single empty table called  flyway_schema_history by default:

This table will be used to track the state of the database.

Flyway will then begin scanning the filesystem or the application’s classpath for migrations. They may be written in SQL or Java.

The migrations are then sorted by version number and applied sequentially.

The schema history table is updated when each migration is applied

With the metadata and the initial state in place, we can start migrating to newer versions.

Flyway will check the filesystem or the application’s classpath for migrations once again. Migrations are compared to the schema history table. They are ignored if their version number is less than or equal to the one of the current version.

The remaining migrations are the pending migrations: available, but not applied.

They are then sorted by version number and executed in order:

The schema history table is updated accordingly.

 Every time the need to change the database arises, whether structure (DDL) or reference data (DML), simply create a new migration with a version number higher than the current one. The next time Flyway starts, it will find it and upgrade the database accordingly

Now let’s see how to use flyway migrations in Spring Boot application

Adding Flyway Dependency

First step is to add the flyway dependency.If you are using Spring Boot’s dependency management feature, you do not need to specify a version number for Flyway

        <dependency>
			<groupId>org.flywaydb</groupId>
			<artifactId>flyway-core</artifactId>
		</dependency>Code language: Java (java)

Preparing Migration Scripts

With Flyway all changes to the database are called migrations. Every migration file has a version, a description and a checksum. The version must be unique. The purpose of the description is solely to help you remember what each migration performs. The checksum’s purpose is to identify intentional/unintentional alterations. They are applied in order exactly once.

Versioned migrations are typically used for:

  • Creating/altering/dropping tables/indexes/foreign keys/enums
  • Reference data updates
  • User data corrections

Each versioned migration must be assigned a unique version. Any version is valid as long as it conforms to the usual dotted notation. For most cases a simple increasing integer should be all you need. However Flyway is quite flexible and all these versions are valid versioned migration versions:

  • 1
  • 01
  • 5.2
  • 1.2.3.4.5.6.7.8.9
  • 205.68
  • 20130115113556
  • 2013.1.15.11.35.56
  • 2013.01.15.11.35.56

SQL-based migrations

Migrations are most commonly written in SQL. This makes it easy to get started and leverage any existing scripts, tools and skills. It gives you access to the full set of capabilities of your database and eliminates the need to understand any intermediate translation layer.

SQL-based migrations are typically used for

  • DDL changes (CREATE/ALTER/DROP statements for TABLES,VIEWS,TRIGGERS,SEQUENCES,…)
  • Simple reference data changes (CRUD in reference data tables)
  • Simple bulk data changes (CRUD in regular data tables)

Naming

In order to be picked up by Flyway, SQL migrations must comply with the following naming pattern:

The file name consists of the following parts:

  • PrefixV for versioned
  • Version: Version with dots or underscores separate as many parts as you like
  • Separator__ (two underscores)
  • Description: Underscores or spaces separate the words
  • Suffix.sql

Notice Title

We can customize the Naming pattern using properties . Please see flyway properties section

Sample migration script.

As we are creating a new database , let’ first create initial database tables.

create sequence hibernate_sequence start with 1 increment by 1;

create table department ( 
                          id integer not null, 
                          name varchar(255), 
                          primary key (id)
                      );

create table employee (  
                       id integer not null, 
                       birth_date date, 
                       email varchar(255), 
                       first_name varchar(255), 
                       gender varchar(255), 
                       hire_date date, 
                       last_name varchar(255), 
                       salary numeric(19,2),
                       department_id integer, 
                       primary key (id)
                    );Code language: Java (java)

Let’s name the file as V1__Initail_Schema.sql and place it resources/db/migration folder.

Note

resources/db/migration folder is the default folder flyway expects the migration files.You can configure the local using flyway properties.

Applying Migrations

To apply migrations in Spring Boot application, you just need to start the application. As we already added dependency Spring Boot will then automatically autowire Flyway with its DataSource and invoke it on startup .Immediately afterwards Flyway will begin scanning the migration files from resources/db/migration folder and sorts them starts applying them.

Flyway by default uses primary configured data source from Spring Boot.

Configuring different Datasource

Flyway can be configured to use different DataSource instead of using primary DataSource from Spring Boot application by using below properties.

spring.flyway.url
spring.flyway.user
spring.flyway.passwordCode language: Java (java)

  INFO  : Root WebApplicationContext: initialization completed in 2912 ms
  INFO  : Flyway Community Edition 8.5.11 by Redgate
  INFO  : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#8.5.11 
  INFO  : HikariPool-1 - Starting...
  INFO  : HikariPool-1 - Start completed.
  INFO  : Database: jdbc:postgresql://localhost:5432/eis (PostgreSQL 13.4)
  INFO  : Successfully validated 1 migration (execution time 00:00.023s)
  INFO  : Creating Schema History table "public"."flyway_schema_history" ...
  INFO  : Current version of schema "public": << Empty Schema >>
  INFO  : Migrating schema "public" to version "1 - Initail Schema"
  INFO  : Successfully applied 1 migration to schema "public", now at version v1 (execution time 00:00.068s)
  INFO  : HHH000204: Processing PersistenceUnitInfo [name: default]

Code language: plaintext (plaintext)

From the startup log we can see that Spring Boot detected flyway and initialized. Flyway applied migration script to database.

If open the database , we can see that there are 2 tables and 1 sequence created as per the migration script.

flyway_schema_history table shows that version 1 is applied successfully.

Applying Another Migration

You can keep on applying migration as per your requirement.

I will try to apply following SQL script to database by adding the script to resource/db/migration folder in a file named V2__Add_Address_Emp_Table.sql


ALTER TABLE EMPLOYEE ADD ADDRESS VARCHAR(255) ;

ALTER TABLE EMPLOYEE  ADD CONSTRAINT FK_EMPLOYEE_DEPARTMENT FOREIGN KEY (DEPARTMENT_ID) REFERENCES DEPARTMENT (ID);Code language: plaintext (plaintext)

V2__Add_Address_Emp_Table.sql

If you start the application, flyway will detect that it currently version1 of schema of and it will detect that new version of schema being added and it will apply that schema.

Please observe that flyway did not apply version1 migration again.

INFO   : Flyway Community Edition 8.5.11 by Redgate
  INFO   : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#8.5.11  
  INFO   : HikariPool-1 - Starting...
  INFO   : HikariPool-1 - Start completed.
  INFO   : Database: jdbc:postgresql://localhost:5432/eis (PostgreSQL 13.4)
  INFO   : Successfully validated 2 migrations (execution time 00:00.021s)
  INFO  : Current version of schema "public": 1
  INFO   : Migrating schema "public" to version "2 - Add Address Emp Table"
  INFO   : Successfully applied 1 migration to schema "public", now at version v2 (execution time 00:00.032s)Code language: plaintext (plaintext)

If you look at the employee table in Db, changes have been applied

If you look at the flyway_schema_history table it shows that 2 migrations are applied to database.

Detecting Changes to Existing Migrations

Once we apply migrations, file should not be changed as Flyway keeps track of applied migrations based on versions and checksum.

Let’s see what happen when we accidently/intentionally introduce changes to the existing migration file by adding some changes

When you start the application, you will see below exception in the logs

org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation Migration checksum mismatch for migration version 2Code language: plaintext (plaintext)

INFO  Database: jdbc:postgresql://localhost:5432/eis (PostgreSQL 13.4)
  WARN 39492 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 2
-> Applied to database : 387136746
-> Resolved locally    : 1892136465
Either revert the changes to the migration, or run repair to update the schema history.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
  INFO 39492 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
  INFO 39492 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
  INFO 39492 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
  INFO 39492 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
ERROR 39492 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 2
-> Applied to database : 387136746
-> Resolved locally    : 1892136465
Either revert the changes to the migration, or run repair to update the schema history.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.20.jar:5.3.20]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.20.jar:5.3.20]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.20.jar:5.3.20]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
	at dev.fullstackcode.eis.SpringbootFlywayDbmigrationApplication.main(SpringbootFlywayDbmigrationApplication.java:10) ~[classes/:na]
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 2
-> Applied to database : 387136746
-> Resolved locally    : 1892136465
Either revert the changes to the migration, or run repair to update the schema history.
Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE
	at org.flywaydb.core.Flyway$1.execute(Flyway.java:130) ~[flyway-core-8.5.11.jar:na]
	at org.flywaydb.core.Flyway$1.execute(Flyway.java:124) ~[flyway-core-8.5.11.jar:na]
	at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:205) ~[flyway-core-8.5.11.jar:na]
	at org.flywaydb.core.Flyway.migrate(Flyway.java:124) ~[flyway-core-8.5.11.jar:na]
	at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.7.0.jar:2.7.0]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.20.jar:5.3.20]
	... 18 common frames omittedCode language: plaintext (plaintext)

How to Add Flyway to Existing Projects

To introduce Flyway to existing database need to use concept called Baseline. First we need to baseline the existing database changes to specific version. Baselining will cause Migrate to ignore all migrations up to and including the baseline version. Newer migrations will then be applied as usual.

1.Take backup of existing data

2.Create SQL script of existing database .

2.Set prepared script version as base line

In Spring Boot application following properties sets baseline

spring.flyway.baseline-on-migrate=true # enables the baselining
spring.flyway.baseline-version=1  # sets baseline versionCode language: Java (java)

If you start the application you will see log like following

 INFO 1060 --- [           main] o.f.c.internal.license.VersionPrinter    :
    INFO 1060 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    INFO 1060 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    INFO 1060 --- [           main] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:postgresql://localhost:5432/Test (PostgreSQL 13.4)
    INFO 1060 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.032s)
    INFO 1060 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "public"."flyway_schema_history" with baseline ...
    INFO 1060 --- [           main] o.f.core.internal.command.DbBaseline     : Successfully baselined schema with version: 1
    INFO 1060 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "public": 1
    INFO 1060 --- [           main] o.f.core.internal.command.DbMigrate      : Schema "public" is up to date. No migration necessary.
    INFO 1060 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]Code language: plaintext (plaintext)

In the database flyway_schema_history will be created and you will see the baseline version set.

You can start adding new migrations and they will be applied as usual.

Resetting the baseline

Baseline is very useful feature. It can be also used in the projects which are already using the Flyway. When the project reaches a particular point and there are several migrations, it may be good to reset your baseline migration. This will help you to decrease the cost of dealing with a large number of scripts, many of which may be obsolete.

Handling Changes to New Migrations in Local Development

While working on new requirements in local development , you might have created migration script and applied to local database and after some time you might have found that you need to change the migration script. How to handle this situation.

You can always add another migration script file to add the missing script or correct the previous script.

The second option is to remove the version entry record from the flyway_schema_history table and undo the applied changes from database and update migration file and re-start the application again.

Notice

Please use the second approach during your local development. Once application moves to integration server add another migration script file to add missing changes.

Spring-Flyway Properties

You can customize the execution of Flyway in Spring Boot using properties.

Some of the properties I mentioned below. For full list of properties ,please visit the Spring Boot documentation

NameDescriptionDefault Value

spring.flyway.locationsLocations of migrations scripts[classpath:db/migration]
spring.flyway.sql-migration-prefixFile name prefix for SQL migrations.V
spring.flyway.sql-migration-separatorFile name separator for SQL migrations.__
spring.flyway.sql-migration-suffixesFile name suffix for SQL migrations.[.sql]
spring.flyway.tableName of the schema history table that will be used by Flyway.flyway_schema_history
spring.flyway.baseline-versionVersion to tag an existing schema with when executing baseline1
spring.flyway.baseline-on-migrateWhether to automatically call baseline when migrating a non-empty schema.False
spring.flyway.urlJDBC url of the database to migrate. If not set, the primary configured data source is used.
spring.flyway.userLogin user of the database to migrate.
spring.flyway.passwordLogin password of the database to migrate.

Trobleshooting

Circular depends-on relationship between ‘flyway’ and ‘entityManagerFactory

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Circular depends-on relationship between 'flyway' and 'entityManagerFactory'
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:317) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.20.jar:5.3.20]Code language: plaintext (plaintext)

If you have configured your application to load initial data during the application startup then you will get this error. You can remove this property or set to false to resolve the error.

spring.jpa.defer-datasource-initialization=true

Found non-empty schema(s) “public” but no schema history table

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "public" but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
  	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.20.jar:5.3.20]
  	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.20.jar:5.3.20]
  	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.20.jar:5.3.20]
  	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
  	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
  	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
  	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
  	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
  	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
  	at dev.fullstackcode.eis.SpringbootFlywayDbmigrationApplication.main(SpringbootFlywayDbmigrationApplication.java:10) ~[classes/:na]
  Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "public" but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
  	at org.flywaydb.core.Flyway$1.execute(Flyway.java:153) ~[flyway-core-8.5.11.jar:na]
  	at org.flywaydb.core.Flyway$1.execute(Flyway.java:124) ~[flyway-core-8.5.11.jar:na]
  	at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:205) ~[flyway-core-8.5.11.jar:na]
  	at org.flywaydb.core.Flyway.migrate(Flyway.java:124) ~[flyway-core-8.5.11.jar:na]
  	at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.7.0.jar:2.7.0]
  	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.20.jar:5.3.20]
  	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.20.jar:5.3.20]
  	... 18 common frames omitted
Code language: plaintext (plaintext)

If you are trying to use flyway migration on database with non-empty schema and without flyway_schema_history table, flyway will throw error as it will not able to determine database current status. To use the flyway with existing schema you need to use the baseline feature. Please refer to How to Add Flyway to Existing Projects section for more details

You can download source code for this blog post from GitHub

You might be also interested in

https://fullstackcode.dev/2022/07/17/flyway-database-migrations-with-commandline-tool/

References

flywaydb.org

Similar Posts