Using Flyway
Flyway is a popular database migration tool that is commonly used in JVM environments.
Quarkus provides first class support for using Flyway as will be explained in this guide.
Setting up support for Flyway
As shown in the Developing with Flyway section, to start using Flyway with your project, you just need to:
-
add your migrations to the
src/main/resources/db/migration
folder as you usually do with Flyway -
activate the
migrate-at-start
option to migrate the schema automatically or inject theFlyway
object and run your migration as you normally do
In your build file, add the following dependencies:
-
the Flyway extension
-
your JDBC driver extension (
quarkus-jdbc-postgresql
,quarkus-jdbc-h2
,quarkus-jdbc-mariadb
, …) -
the MariaDB/MySQL support is now in a separate dependency, MariaDB/MySQL users need to add the
flyway-mysql
dependency from now on. -
the Microsoft SQL Server support is now in a separate dependency, Microsoft SQL Server users need to add the
flyway-sqlserver
dependency from now on. -
the Oracle support is now in a separate dependency, Oracle users need to add the
flyway-database-oracle
dependency from now on.
<!-- Flyway specific dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-flyway</artifactId>
</dependency>
<!-- Flyway SQL Server specific dependencies -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-sqlserver</artifactId>
</dependency>
<!-- Flyway MariaDB/MySQL specific dependencies -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
<!-- Flyway Oracle specific dependencies -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-oracle</artifactId>
</dependency>
<!-- JDBC driver dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
// Flyway specific dependencies
implementation("io.quarkus:quarkus-flyway")
// Flyway SQL Server specific dependencies
implementation("org.flywaydb:flyway-sqlserver")
// Flyway MariaDB/MySQL specific dependencies
implementation("org.flywaydb:flyway-mysql")
// Flyway Oracle specific dependencies
implementation("org.flywaydb:flyway-database-oracle")
// JDBC driver dependencies
implementation("io.quarkus:quarkus-jdbc-postgresql")
Flyway support relies on the Quarkus datasource config. It can be
customized for the default datasource as well as for every
named datasource. First, you need to add the
datasource config to the application.properties
file in order to allow Flyway to
manage the schema. Also, you can customize the Flyway behaviour by using
the following properties:
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
Whether Flyway is enabled during the build. If Flyway is disabled, the Flyway beans won’t be created and Flyway won’t be usable. Environment variable: Show more |
boolean |
|
Comma-separated list of locations to scan recursively for migrations. The location type is determined by its prefix. Unprefixed locations or locations starting with classpath: point to a package on the classpath and may contain both SQL and Java-based migrations. Locations starting with filesystem: point to a directory on the filesystem, may only contain SQL migrations and are only scanned recursively down non-hidden directories. Environment variable: Show more |
list of string |
|
Comma-separated list of fully qualified class names of Callback implementations to use to hook into the Flyway lifecycle. The Environment variable: Show more |
list of string |
|
Flag to activate/deactivate Flyway for a specific datasource at runtime. Environment variable: Show more |
boolean |
|
The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will wait up to the configured Environment variable: Show more |
int |
|
The maximum time between retries when attempting to connect to the database. This will cap the interval between connect retries to the value provided. Environment variable: Show more |
|
|
Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default schema for the database connection. Consequences:
Environment variable: Show more |
string |
|
The JDBC URL that Flyway uses to connect to the database. Falls back to the datasource URL if not specified. Environment variable: Show more |
string |
|
The username that Flyway uses to connect to the database. If no specific JDBC URL is configured, falls back to the datasource username if not specified. Environment variable: Show more |
string |
|
The password that Flyway uses to connect to the database. If no specific JDBC URL is configured, falls back to the datasource password if not specified. Environment variable: Show more |
string |
|
Comma-separated case-sensitive list of schemas managed by Flyway. The first schema in the list will be automatically set as the default one during the migration. It will also be the one containing the schema history table. Environment variable: Show more |
list of string |
|
The name of Flyway’s schema history table. By default (single-schema mode), the schema history table is placed in the default schema for the connection provided by the datasource. When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema of the list. Environment variable: Show more |
string |
|
The file name prefix for versioned SQL migrations. Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix , which using the defaults translates to V1.1__My_description.sql Environment variable: Show more |
string |
|
The file name prefix for repeatable SQL migrations. Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix , which using the defaults translates to R__My_description.sql Environment variable: Show more |
string |
|
true to execute Flyway clean command automatically when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to prevent Flyway clean operations, false otherwise. Environment variable: Show more |
boolean |
|
true to automatically call clean when a validation error occurs, false otherwise. Environment variable: Show more |
boolean |
|
true to execute Flyway automatically when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute a Flyway repair command when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute a Flyway validate command when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute Flyway baseline before migrations This flag is ignored if the flyway_schema_history table exists in the current schema or if the current schema is empty. Note that this will not automatically call migrate, you must either enable baselineAtStart or programmatically call flyway.migrate(). Environment variable: Show more |
boolean |
|
true to execute Flyway baseline automatically when the application starts. This flag is ignored if the flyway_schema_history table exists in the current schema. This will work even if the current schema is empty. Environment variable: Show more |
boolean |
|
The initial baseline version. Environment variable: Show more |
string |
|
The description to tag an existing schema with when executing baseline. Environment variable: Show more |
string |
|
Whether to automatically call validate when performing a migration. Environment variable: Show more |
boolean |
|
Allows migrations to be run "out of order". Environment variable: Show more |
boolean |
|
Ignore missing migrations when reading the history table. When set to true migrations from older versions present in the history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) the validation step will fail. Environment variable: Show more |
boolean |
|
Ignore future migrations when reading the history table. When set to true migrations from newer versions present in the history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) the validation step will fail. Environment variable: Show more |
boolean |
|
Whether Flyway should attempt to create the schemas specified in the schemas property Environment variable: Show more |
boolean |
|
Prefix of every placeholder (default: ${ ) Environment variable: Show more |
string |
|
Suffix of every placeholder (default: } ) Environment variable: Show more |
string |
|
The SQL statements to run to initialize a new database connection immediately after opening it. Environment variable: Show more |
string |
|
Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be useful to check that errors such as case sensitivity in migration prefixes have been corrected. Environment variable: Show more |
boolean |
|
Ignore migrations during validate and repair according to a given list of patterns (see https://flywaydb.org/documentation/configuration/parameters/ignoreMigrationPatterns for more information). When this configuration is set, the ignoreFutureMigrations and ignoreMissingMigrations settings are ignored. Patterns are comma separated. Environment variable: Show more |
list of string |
|
Comma-separated list of locations to scan recursively for migrations. The location type is determined by its prefix. Unprefixed locations or locations starting with classpath: point to a package on the classpath and may contain both SQL and Java-based migrations. Locations starting with filesystem: point to a directory on the filesystem, may only contain SQL migrations and are only scanned recursively down non-hidden directories. Environment variable: Show more |
list of string |
|
Comma-separated list of fully qualified class names of Callback implementations to use to hook into the Flyway lifecycle. The Environment variable: Show more |
list of string |
|
Sets the placeholders to replace in SQL migration scripts. Environment variable: Show more |
|
|
Flag to activate/deactivate Flyway for a specific datasource at runtime. Environment variable: Show more |
boolean |
|
The maximum number of retries when attempting to connect to the database. After each failed attempt, Flyway will wait up to the configured Environment variable: Show more |
int |
|
The maximum time between retries when attempting to connect to the database. This will cap the interval between connect retries to the value provided. Environment variable: Show more |
|
|
Sets the default schema managed by Flyway. This schema name is case-sensitive. If not specified, but schemas is, Flyway uses the first schema in that list. If that is also not specified, Flyway uses the default schema for the database connection. Consequences:
Environment variable: Show more |
string |
|
The JDBC URL that Flyway uses to connect to the database. Falls back to the datasource URL if not specified. Environment variable: Show more |
string |
|
The username that Flyway uses to connect to the database. If no specific JDBC URL is configured, falls back to the datasource username if not specified. Environment variable: Show more |
string |
|
The password that Flyway uses to connect to the database. If no specific JDBC URL is configured, falls back to the datasource password if not specified. Environment variable: Show more |
string |
|
Comma-separated case-sensitive list of schemas managed by Flyway. The first schema in the list will be automatically set as the default one during the migration. It will also be the one containing the schema history table. Environment variable: Show more |
list of string |
|
The name of Flyway’s schema history table. By default (single-schema mode), the schema history table is placed in the default schema for the connection provided by the datasource. When the flyway.schemas property is set (multi-schema mode), the schema history table is placed in the first schema of the list. Environment variable: Show more |
string |
|
The file name prefix for versioned SQL migrations. Versioned SQL migrations have the following file name structure: prefixVERSIONseparatorDESCRIPTIONsuffix , which using the defaults translates to V1.1__My_description.sql Environment variable: Show more |
string |
|
The file name prefix for repeatable SQL migrations. Repeatable SQL migrations have the following file name structure: prefixSeparatorDESCRIPTIONsuffix , which using the defaults translates to R__My_description.sql Environment variable: Show more |
string |
|
true to execute Flyway clean command automatically when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to prevent Flyway clean operations, false otherwise. Environment variable: Show more |
boolean |
|
true to automatically call clean when a validation error occurs, false otherwise. Environment variable: Show more |
boolean |
|
true to execute Flyway automatically when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute a Flyway repair command when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute a Flyway validate command when the application starts, false otherwise. Environment variable: Show more |
boolean |
|
true to execute Flyway baseline before migrations This flag is ignored if the flyway_schema_history table exists in the current schema or if the current schema is empty. Note that this will not automatically call migrate, you must either enable baselineAtStart or programmatically call flyway.migrate(). Environment variable: Show more |
boolean |
|
true to execute Flyway baseline automatically when the application starts. This flag is ignored if the flyway_schema_history table exists in the current schema. This will work even if the current schema is empty. Environment variable: Show more |
boolean |
|
The initial baseline version. Environment variable: Show more |
string |
|
The description to tag an existing schema with when executing baseline. Environment variable: Show more |
string |
|
Whether to automatically call validate when performing a migration. Environment variable: Show more |
boolean |
|
Allows migrations to be run "out of order". Environment variable: Show more |
boolean |
|
Ignore missing migrations when reading the history table. When set to true migrations from older versions present in the history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) the validation step will fail. Environment variable: Show more |
boolean |
|
Ignore future migrations when reading the history table. When set to true migrations from newer versions present in the history table but absent in the configured locations will be ignored (and logged as a warning), when false (the default) the validation step will fail. Environment variable: Show more |
boolean |
|
Sets the placeholders to replace in SQL migration scripts. Environment variable: Show more |
|
|
Whether Flyway should attempt to create the schemas specified in the schemas property Environment variable: Show more |
boolean |
|
Prefix of every placeholder (default: ${ ) Environment variable: Show more |
string |
|
Suffix of every placeholder (default: } ) Environment variable: Show more |
string |
|
The SQL statements to run to initialize a new database connection immediately after opening it. Environment variable: Show more |
string |
|
Whether to validate migrations and callbacks whose scripts do not obey the correct naming convention. A failure can be useful to check that errors such as case sensitivity in migration prefixes have been corrected. Environment variable: Show more |
boolean |
|
Ignore migrations during validate and repair according to a given list of patterns (see https://flywaydb.org/documentation/configuration/parameters/ignoreMigrationPatterns for more information). When this configuration is set, the ignoreFutureMigrations and ignoreMissingMigrations settings are ignored. Patterns are comma separated. Environment variable: Show more |
list of string |
About the Duration format
To write duration values, use the standard You can also use a simplified format, starting with a number:
In other cases, the simplified format is translated to the
|
Developing with Flyway
The following is an example for the application.properties
file:
# configure your datasource
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=sarah
quarkus.datasource.password=connor
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydatabase
# Run Flyway migrations automatically
quarkus.flyway.migrate-at-start=true
# More Flyway configuration options
# quarkus.flyway.baseline-on-migrate=true
# quarkus.flyway.baseline-version=1.0.0
# quarkus.flyway.baseline-description=Initial version
# quarkus.flyway.connect-retries=10
# quarkus.flyway.schemas=TEST_SCHEMA
# quarkus.flyway.table=flyway_quarkus_history
# quarkus.flyway.locations=db/location1,db/location2
# quarkus.flyway.sql-migration-prefix=X
# quarkus.flyway.repeatable-sql-migration-prefix=K
Add a SQL migration to the default folder following the Flyway naming
conventions: src/main/resources/db/migration/V1.0.0__Quarkus.sql
CREATE TABLE quarkus
(
id INT,
name VARCHAR(20)
);
INSERT INTO quarkus(id, name)
VALUES (1, 'QUARKED');
Now you can start your application and Quarkus will run the Flyway’s migrate method according to your config.
With quarkus.flyway.migrate-at-start=true , as in the example above,
Quarkus will execute the Flyway migration as part of the
application startup.
|
@ApplicationScoped
public class MigrationService {
// You can Inject the object if you want to use it manually
@Inject
Flyway flyway; (1)
public void checkMigration() {
// This will print 1.0.0
System.out.println(flyway.info().current().getVersion().toString());
}
}
1 | Inject the Flyway object if you want to use it directly |
In dev mode Quarkus will automatically restart the application if any of the
existing migration scripts get modified. If you want to take advantage of
this while developing and testing new migration scripts, you will want to
set %dev.quarkus.flyway.clean-at-start=true , so that Flyway actually runs
the modified migration.
|
Repairing the Flyway schema history table
There are different scenarios which may require repairing the Flyway schema history table. One such scenario is when a migration fails in a database which doesn’t support transactional DDL statements.
In such situations the
Flyway repair
command comes in handy. In Quarkus this can either be executed
automatically before the migration by setting
quarkus.flyway.repair-at-start=true
or manually by injecting the Flyway
object and calling Flyway#repair()
.
Multiple datasources
Flyway can be configured for multiple datasources. The Flyway properties are prefixed exactly the same way as the named datasources, for example:
quarkus.datasource.db-kind=h2
quarkus.datasource.username=username-default
quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default
quarkus.datasource.jdbc.max-size=13
quarkus.datasource.users.db-kind=h2
quarkus.datasource.users.username=username1
quarkus.datasource.users.jdbc.url=jdbc:h2:tcp://localhost/mem:users
quarkus.datasource.users.jdbc.max-size=11
quarkus.datasource.inventory.db-kind=h2
quarkus.datasource.inventory.username=username2
quarkus.datasource.inventory.jdbc.url=jdbc:h2:tcp://localhost/mem:inventory
quarkus.datasource.inventory.jdbc.max-size=12
# Flyway configuration for the default datasource
quarkus.flyway.schemas=DEFAULT_TEST_SCHEMA
quarkus.flyway.locations=db/default/location1,db/default/location2
quarkus.flyway.migrate-at-start=true
# Flyway configuration for the "users" datasource
quarkus.flyway.users.schemas=USERS_TEST_SCHEMA
quarkus.flyway.users.locations=db/users/location1,db/users/location2
quarkus.flyway.users.migrate-at-start=true
# Flyway configuration for the "inventory" datasource
quarkus.flyway.inventory.schemas=INVENTORY_TEST_SCHEMA
quarkus.flyway.inventory.locations=db/inventory/location1,db/inventory/location2
quarkus.flyway.inventory.migrate-at-start=true
Notice there’s an extra bit in the key. The syntax is as follows:
quarkus.flyway.[optional name.][datasource property]
.
Without configuration, Flyway is set up for every datasource using the default settings. |
Customizing Flyway
In cases where Flyway needs to be configured in addition to the
configuration options that Quarkus provides, the
io.quarkus.flyway.FlywayConfigurationCustomizer
class comes in handy.
To customize Flyway for the default datasource, simply add a bean like so:
@Singleton
public static class MyCustomizer implements FlywayConfigurationCustomizer {
@Override
public void customize(FluentConfiguration configuration) {
// do something with configuration
}
}
When named datasources are used, the @FlywayDataSource
annotation can be
used to specify the datasource to which the customizer applies. For
example, if there are multiple datasources one of which is called users
and customization of Flyway is needed for only that datasource, then the
following code can be used:
@Singleton
@FlywayDataSource("users")
public static class UsersCustomizer implements FlywayConfigurationCustomizer {
@Override
public void customize(FluentConfiguration configuration) {
// do something with configuration
}
}
Using the Flyway object
In case you are interested in using the Flyway
object directly, you can
inject it as follows:
@ApplicationScoped
public class MigrationService {
// You can Inject the object if you want to use it manually
@Inject
Flyway flyway; (1)
@Inject
@FlywayDataSource("inventory") (2)
Flyway flywayForInventory;
@Inject
@Named("flyway_users") (3)
Flyway flywayForUsers;
public void checkMigration() {
// Use the flyway instance manually
flyway.clean(); (4)
flyway.migrate();
// This will print 1.0.0
System.out.println(flyway.info().current().getVersion().toString());
}
}
1 | Inject the Flyway object if you want to use it directly |
2 | Inject Flyway for named datasources using the Quarkus FlywayDataSource
qualifier |
3 | Inject Flyway for named datasources |
4 | Use the Flyway instance directly |
Flyway and Hibernate ORM
When using Flyway together with Hibernate ORM, you can use the Dev UI to generate the initial schema creation script.
You can find more information about this feature in the Hibernate ORM guide.
Flyway on Kubernetes
Sometimes, it’s helpful not to execute Flyway initialization on each application startup. One such example is when deploying
on Kubernetes, where it doesn’t make sense to execute Flyway on every single
replica. Instead it’s desirable to execute it once and then start the actual
application without Flyway. To support this use case, when generating
manifests for Kubernetes the generated manifests contain a Kubernetes
initialization Job
for Flyway. The Job
performs initialization and the
actual Pod
, will starts once the Job
is successfully completed.
Disabling
The feature is enabled by default and can be globally disabled, using:
quarkus.kubernetes.init-task-defaults.enabled=false
or on OpenShift:
quarkus.openshift.init-task-defaults.enabled=false
Using a custom image that controls waiting for the Job
To change the wait-for
image which by default is
groundnuty/k8s-wait-for:no-root-v1.7
you can use:
quarkus.kubernetes.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0
or on Openshift:
quarkus.openshift.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0
Note: In this context globally means for all extensions that support init task externalization
.