Skip to main content

Migration Applying

Atlas has its own migration execution engine, that works with the Atlas migration file format, e.g. migration files generated by atlas migrate diff.

Arguments

atlas migrate apply accepts one positional integer argument to specify how many pending migration files to run.

  • atlas migrate apply run all pending migrations
  • atlas migrate apply 2 run at most 2 pending migrations

Flags

When using migrate apply to apply migrations, users must supply multiple parameters:

  • --url the URL to the database to apply migrations on.
  • --dir the URL of the migration directory, by default it is file://migrations, e.g a directory named migrations in the current working directory.

Schema Revision Information

Atlas saves information about the applied migrations on a table called atlas_schema_revisions in the connected database schema (e.g. mysql://user@host/my_schema or postgres://user@host/db?search_path=my_schema). If the database connection is not bound to a specific schema (e.g. mysql://user@host/ or postgres://user@host/db), the table is stored in its own schema called atlas_schema_revisions. This behavior can be changed by setting the schema manually:

  • --revisions-schema my_schema to store the data in my_schema.atlas_schema_revisions.

Transaction Configuration

By default, Atlas creates one transaction per migration file and will roll back that transaction if a statement in the wrapped migration fails to execute. Atlas supports three different transaction modes:

  • --tx-mode file (default) will wrap each pending migration into its own transaction.
  • --tx-mode all will wrap all pending migration files into one transaction.
  • --tx-mode none will not create any transaction. If a statement fails, the execution will stop. However, Atlas is smart enough to detect which statement fails and on another migration attempt will continue with the failed statement. This means altering the migration file from the failed statements onwards is safe and recommended.
caution

Please be aware, that non DDL transactional databases like MySQL (due to implicit commits) can not be safely rolled back completely, and you might end up with a mismatched schema and revision table state. Atlas will handle those cases in future releases. A good source of information can be found in the PostgreSQL wiki.

Existing Databases

If you have an existing database project and want to switch over to Atlas Versioned Migrations, you need to provide Atlas with a starting point. The first step is to create a migration file reflecting the current schema state. This can be easily done:

atlas migrate diff my_baseline \
--dir "file://migrations" \
--to "mysql://root:pass@remote:3306/my_schema"
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`age` bigint(20) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `age` (`age`)
)

On your first migration execution attempt, you can then specify a baseline version. Atlas will mark this version as already applied and proceed with the next version:

  • --baseline 1 will skip all files including version 1 (1_baseline.sql) and proceed with the next version (2_add_pets_table).

If your database does contain resources but no revision information yet, Atlas will refuse to execute migration files. One way to override that behavior is by using the --baseline flag above. However, e.g. in cases where the existing tables are not managed by Atlas at all and should not be part of a baseline file, you can run the initial migration attempt by providing the following flag:

  • --allow-dirty to allow starting migration execution on a non-clean database.

--allow-dirty and --baseline are mutually exclusive.

Dry Run

If you want to check what exactly Atlas would do when attempting a migration execution, you can provide the --dry-run flag:

  • --dry-run to not execute any SQL but print it on the screen.

Examples

First time apply with baseline on production environment:

atlas migrate apply \
--env "production" \
--baseline "20220811074144"

Execute 1 pending migration file, but don't run, but print SQL statements on screen:

atlas migrate apply 1 \
--env "production" \
--baseline "20220811074144" \
--dry-run

Specify revision table schema and custom migration directory path:

atlas migrate apply \
--url "mysql://root:pass@remote:3306/my_database" \
--revisions-schema "atlas_migration_history" \
--dir "file://custom/path/to/dir"

Ignore unclean database and run the first 3 migrations:

atlas migrate apply 3 \
--url "mysql://root:pass@remote:3306/my_database" \
--dir "file://custom/path/to/dir"

Run all pending migrations, but do not use a transaction:

atlas migrate apply \
--url "mysql://root:pass@remote:3306/my_database" \
--tx-mode "none"