Migrating from Flyway to Atlas
TL;DR
- Flyway (Redgate) is a battle-tested database migration tool that's lightweight, reliable, and widely adopted across many programming languages and environments.
- Atlas is an open-source tool for inspecting, planning, linting and executing schema changes to your database.
- Developers using Flyway that want to unlock Atlas's advanced schema management capabilities can follow this guide to seamlessly import an existing project to Atlas.
Prerequisites
Before you begin, make sure you have:
- Access to your Flyway migration directory and database
- Docker installed and running
- Atlas CLI installed
If you do not have Atlas installed yet, choose your platform below:
- macOS + Linux
- Homebrew
- Docker
- Windows
- Manual Installation
To download and install the latest release of the Atlas CLI, simply run the following in your terminal:
curl -sSf https://atlasgo.sh | sh
Get the latest release with Homebrew:
brew install ariga/tap/atlas
To pull the Atlas image and run it as a Docker container:
docker pull arigaio/atlas
docker run --rm arigaio/atlas --help
If the container needs access to the host network or a local directory, use the --net=host
flag and mount the desired
directory:
docker run --rm --net=host \
-v $(pwd)/migrations:/migrations \
arigaio/atlas migrate apply
--url "mysql://root:pass@:3306/test"
Download the latest release and move the atlas binary to a file location on your system PATH.
Step 1 – Import Your Existing Migration Files
Atlas can convert Flyway migration files to Atlas format using the Migration Directory Import feature:
# Convert Flyway migrations to Atlas format
atlas migrate import \
--from "file://migrations?format=flyway" \
--to "file://atlas-migrations"
What this does:
- Converts
V__
(versioned) andR__
(repeatable) Flyway files into Atlas migrations - Generates an
atlas.sum
file to track checksums - Skips
U__
(undo) files, as Atlas computes down migrations dynamically
Additional details about the import process:
- Repeatable migrations (
R__
prefix) are converted to versioned migrations that end with anR
suffix (for example,R__view.sql
→1R_view.sql
). - Undo migrations (
U__
prefix) are not imported because Atlas calculates down migrations automatically. - Comments that don’t directly precede SQL statements may be lost during conversion. Review the generated files if you rely on inline documentation.
- If you need repeatable-like behaviour after import, use SQL hooks to recreate views, procedures, or other objects on each deployment.
Step 2 – Configure Atlas
Before we look at the Atlas configuration, here’s a typical Flyway configuration that manages multiple environments:
databaseType = "MySql"
id = "8b52a0b7-07aa-46ba-883c-fdf6ef5cfe3d"
name = "FlywayAutoPilot"
[flyway]
locations = [ "filesystem:migrations" ]
mixed = true
outOfOrder = true
[flyway.check]
majorTolerance = 0
[flywayDesktop]
developmentEnvironment = "development"
shadowEnvironment = "shadow"
[flywayDesktop.generate]
undoScripts = true
[redgateCompare]
filterFile = "filter.rgf"
[environments.development]
url = "jdbc:mysql://localhost:3306"
schemas = [ "dev" ]
displayName = "Development database"
[environments.test]
url = "jdbc:mysql://localhost:3308"
schemas = [ "test" ]
displayName = "Test database"
[environments.prod]
url = "jdbc:mysql://localhost:3306"
schemas = [ "prod" ]
displayName = "Production database"
[environments.shadow]
url = "jdbc:mysql://localhost:3306"
schemas = [ "shadow" ]
displayName = "Shadow database"
[environments.check]
url = "jdbc:mysql://localhost:3306"
schemas = [ "check" ]
displayName = "Check database"
[environments.build]
url = "jdbc:mysql://localhost:3306"
schemas = [ "build" ]
displayName = "Build database"
Atlas simplifies this significantly. Since Atlas utilizes a dev-database, an ephemeral Docker container used for migration validation and planning, you only need to configure your real application environments:
env "local" {
url = "mysql://root:admin@localhost:3306/dev"
dev = "docker://mysql/8/dev"
migration {
dir = "file://atlas-migrations"
}
}
env "production" {
url = "mysql://user:pass@prod-server:3306/prod"
dev = "docker://mysql/8/dev"
migration {
dir = "file://atlas-migrations"
}
}
Atlas uses standard URL format (mysql://user:pass@host:port/database
) instead of JDBC URLs (jdbc:mysql://host:port
).
Step 3 – Set the Baseline on Your Existing Database
Like many other database schema management tools, Atlas uses a metadata table on the target database to keep track of which migrations were already applied. When starting to use Atlas on an existing database that was previously managed by Flyway, we must inform Atlas that all migrations up to a certain version were already applied.
Let's try to run Atlas's migrate apply
command on a database that is currently managed by Flyway:
atlas migrate apply --env local
Atlas will return an error because it detects that the database is not "clean" (it already contains Flyway's migration history):
Error: sql/migrate: connected database is not clean: found table "flyway_schema_history" in schema "your_db". baseline version or allow-dirty is required
To fix this, use the --baseline
flag to tell Atlas that the database is already at a certain version. Use the latest migration version that has been applied by Flyway:
atlas migrate apply --env local --baseline 004
Atlas reports that there's nothing new to run:
No migration files to execute
Perfect! Next, let's verify that Atlas is aware of what migrations were already applied by using the migrate status
command:
atlas migrate status --env local
Atlas reports:
Migration Status: OK
-- Current Version: 004
-- Next Version: Already at latest version
-- Executed Files: 1
-- Pending Files: 0
Great! Atlas now recognizes your existing database state and is ready to manage future migrations.
Next Steps
- Manage your migrations with Atlas: versioned workflows or declarative workflows
- Explore migration linting and schema monitoring to strengthen your workflow.
- Plug Atlas into your CI/CD pipeline for automatic migration checks.
Need Help?
Click the Intercom bubble on the site or schedule a demo with our team.