1. Introduction
In this short tutorial, we’ll explore a couple of ways to rollback a migration with Flyway.
2. Simulate Rollback with a Migration
In this section, we’ll rollback our database using a standard migration file.
In our examples, we’ll use the command-line version of Flyway. However, the core principles are equally applicable to the other formats, such as the core API, Maven plugin, etc.
2.1. Create Migration
First, let’s add a new book table to our database. In order to do this, we’ll create a migration file called V1_0__create_book_table.sql:
create table book (
id numeric,
title varchar(128),
author varchar(256),
constraint pk_book primary key (id)
);
Secondly, let’s apply the migration:
./flyway migrate
2.2. Simulate Rollback
Then, at some point, say we need to reverse the last migration.
In order to restore the database to before the book table was created, let’s create migration called V2_0__drop_table_book.sql:
drop table book;
Next, let’s apply the migration:
./flyway migrate
Finally, we can check the history of all the migrations using:
./flyway info
which gives us the following output:
+-----------+---------+-------------------+------+---------------------+---------+
| Category | Version | Description | Type | Installed On | State |
+-----------+---------+-------------------+------+---------------------+---------+
| Versioned | 1.0 | create book table | SQL | 2020-08-29 16:07:43 | Success |
| Versioned | 2.0 | drop table book | SQL | 2020-08-29 16:08:15 | Success |
+-----------+---------+-------------------+------+---------------------+---------+
Notice that our second migration ran successfully.
As far as Flyway is concerned, the second migration file is just another standard migration. The actual restoring of the database to the previous version is done entirely through SQL. For example, in our case, the SQL of dropping the table is the opposite of the first migration, which creates the table.
Using this method, the audit trail doesn’t show us that the second migration is related to the first, as they have different version numbers. In order to get such an audit trail, we need to use Flyway Undo.
3. Using Flyway Undo
Firstly, it’s important to note that Flyway Undo is a commercial feature of Flyway and isn’t available in the Community Edition. Therefore, we’ll need either the Pro Edition or Enterprise Edition in order to use this feature.
3.1. Create Migration Files
First, let’s create a migration file called V1_0__create_book_table.sql:
create table book (
id numeric,
title varchar(128),
author varchar(256),
constraint pk_book primary key (id)
);
Secondly, let’s create the corresponding undo migration file U1_0__create_book_table.sql:
drop table book;
In our undo migration, notice how the filename-prefix is ‘U’ compared with the normal migration prefix of ‘V’. Also, in our undo migration files, we write the SQL that reverses the changes of the corresponding migration file. In our case, we’re dropping the table that’s created by the normal migration.
3.2. Apply Migrations
Next, let’s check the current state of the migrations:
./flyway -pro info
This gives us the following output:
+-----------+---------+-------------------+------+--------------+---------+----------+
| Category | Version | Description | Type | Installed On | State | Undoable |
+-----------+---------+-------------------+------+--------------+---------+----------+
| Versioned | 1.0 | create book table | SQL | | Pending | Yes |
+-----------+---------+-------------------+------+--------------+---------+----------+
Notice the last column, Undoable, which indicates Flyway has detected an undo migration file that accompanies our normal migration file.
Next, let’s apply our migrations:
./flyway migrate
When it completes, our migrations are complete, and our schema has a new book table:
List of relations
Schema | Name | Type | Owner
--------+-----------------------+-------+----------
public | book | table | baeldung
public | flyway_schema_history | table | baeldung
(2 rows)
3.3. Rollback the Last Migration
Finally, let’s undo the last migration using the command line:
./flyway -pro undo
After the command has run successfully, we can check the status of the migrations again:
./flyway -pro info
which gives us the following output:
+-----------+---------+-------------------+----------+---------------------+---------+----------+
| Category | Version | Description | Type | Installed On | State | Undoable |
+-----------+---------+-------------------+----------+---------------------+---------+----------+
| Versioned | 1.0 | create book table | SQL | 2020-08-22 15:48:00 | Undone | |
| Undo | 1.0 | create book table | UNDO_SQL | 2020-08-22 15:49:47 | Success | |
| Versioned | 1.0 | create book table | SQL | | Pending | Yes |
+-----------+---------+-------------------+----------+---------------------+---------+----------+
Notice how the undo has been successful, and the first migration is back to pending. Also, in contrast to the first method, the audit trail clearly shows the migrations that were rolled back.
Although Flyway Undo can be useful, it assumes that the whole migration has succeeded. For example, it may not work as expected if a migration fails partway through.
4. Conclusion
In this short tutorial, we looked at restoring our database using a standard migration. We also looked at the official way of rolling back migrations using Flyway Undo. As usual, all of our code that relates to this tutorial can be found over on GitHub.