Quick Introduction
Atlas is a language-independent tool for managing and migrating database schemas using modern DevOps principles.It offers two workflows:
Declarative: Similar to Terraform, Atlas compares the current state of the database to the desired state, asdefined in anHCL,SQL, orORM schema.Based on this comparison, it generates and executes a migration plan to transition the database to its desired state.
Versioned: Unlike other tools, Atlas automatically plans schema migrations for you. Users can describe their desireddatabase schema inHCL,SQL, or their chosenORM,and by utilizing Atlas, they can plan, lint, and apply the necessary migrations to the database.
Installation
- 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 withHomebrew:
brewinstall 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 desireddirectory:
docker run--rm--net=host\
-v$(pwd)/migrations:/migrations\
arigaio/atlas migrate apply
--url"mysql://root:pass@:3306/test"
Download thelatest release andmove the atlas binary to a file location on your system PATH.
The default binaries distributed in official releases are released under theAtlas EULA. If you would like obtain a copy of AtlasCommunity Edition (under an Apache 2 license) follow the instructionshere.
Start a local database container
For the purpose of this guide, we will start a local Docker container running MySQL.
docker run--rm-d--name atlas-demo-p3306:3306-eMYSQL_ROOT_PASSWORD=pass-eMYSQL_DATABASE=example mysql
For this example, we will start with a schema that represents ausers
table, in which each user has an ID and a name:
CREATEtable users(
idintPRIMARYKEY,
namevarchar(100)
);
To create the table above on our local database, we can run the following command:
dockerexec atlas-demo mysql-ppass-e'CREATE table example.users(id int PRIMARY KEY, name varchar(100))'
Inspecting our database
Theatlas schema inspect
command supports reading the database description provided by a URL and outputting it inthree different formats:Atlas DDL (default), SQL, and JSON. In this guide, we willdemonstrate the flow using both the Atlas DDL and SQL formats, as the JSON format is often used for processing theoutput usingjq
.
- Atlas DDL (HCL)
- SQL
To inspect our locally-running MySQL instance, use the-u
flag and write the output to a file namedschema.hcl
:
atlas schema inspect-u"mysql://root:pass@localhost:3306/example"> schema.hcl
Open theschema.hcl
file to view the Atlas schema that describes our database.
table"users"{
schema= schema.example
column"id"{
null=false
type= int
}
column"name"{
null=true
type= varchar(100)
}
primary_key{
columns=[column.id]
}
}
This block represents atable resource withid
, andname
columns. Theschema
field references theexample
schema that is defined elsewherein this document. In addition, theprimary_key
sub-block defines theid
column asthe primary key for the table. Atlas strives to mimic the syntax of the database that the user is working against. In this case, thetype for theid
column isint
, andvarchar(100)
for thename
column.
To inspect our locally-running MySQL instance, use the-u
flag and write the output to a file namedschema.sql
:
atlas schema inspect-u"mysql://root:pass@localhost:3306/example"--format'{{ sql . }}'> schema.sql
Open theschema.sql
file to view the inspected SQL schema that describes our database.
-- create "users" table
CREATETABLE`users`(
`id`intNOTNULL,
`name`varchar(100)NULL,
PRIMARYKEY(`id`)
)CHARSET utf8mb4COLLATE utf8mb4_0900_ai_ci;
Now, consider we want to add ablog_posts
table and have our schema represent a simplifiedblogging system.
Let's add the following to our inspected schema, and use Atlas to plan and apply the changes to our database.
- Atlas DDL (HCL)
- SQL
Edit theschema.hcl
file and add the followingtable
block:
table"blog_posts"{
schema= schema.example
column"id"{
null=false
type= int
}
column"title"{
null=true
type= varchar(100)
}
column"body"{
null=true
type= text
}
column"author_id"{
null=true
type= int
}
primary_key{
columns=[column.id]
}
foreign_key"author_fk"{
columns=[column.author_id]
ref_columns=[table.users.column.id]
}
}
In addition to the elements we saw in theusers
table, here we can find aforeign keyblock, declaring that theauthor_id
column references theid
column on theusers
table.
Edit theschema.sql
file and add the followingCREATE TABLE
statement:
-- create "blog_posts" table
CREATETABLE`blog_posts`(
`id`intNOTNULL,
`title`varchar(100)NULL,
`body`textNULL,
`author_id`intNULL,
PRIMARYKEY(`id`),
CONSTRAINT`author_fk`FOREIGNKEY(`author_id`)REFERENCES`example`.`users`(`id`)
);
Now, let's apply these changes by running a migration.In Atlas, migrations can be applied in two types of workflows:declarative andversioned.
Declarative Migrations
The declarative approach requires the user to define thedesired end schema, and Atlas providesa safe way to alter the database to get there. Let's see this in action.
Continuing the example, in order to apply the changes to our database we will run theapply
command:
- Atlas DDL (HCL)
- SQL
atlas schema apply\
-u"mysql://root:pass@localhost:3306/example"\
--to file://schema.hcl
atlas schema apply\
-u"mysql://root:pass@localhost:3306/example"\
--to file://schema.sql\
--dev-url"docker://mysql/8/example"
Atlas presents the plan it created by displaying the SQL statements. For example, for a MySQL database we will seethe following:
-- Planned Changes:
-- Create "blog_posts" table
CREATE TABLE `example`.`blog_posts` (`id` int NOT NULL, `title` varchar(100) NULL, `body` text NULL, `author_id` int NULL, PRIMARY KEY (`id`), INDEX `author_id` (`author_id`), CONSTRAINT `author_fk` FOREIGN KEY (`author_id`) REFERENCES `example`.`users` (`id`))
Use the arrow keys to navigate: ↓ ↑ → ←
? Are you sure?:
▸ Apply
Abort
Apply the changes, and that's it! You have successfully run a declarative migration.
To ensure that the changes have been made to the schema, you can run theinspect
command again. This time, we usethe--web
/-w
flag to open the Atlas Web UI and view the schema.
atlas schema inspect\
-u"mysql://root:pass@localhost:3306/example"\
--web
If you are using an old version of Atlas, you may need to replace the--web
flag with--visualize
.
Versioned Migrations
Alternatively, the versioned migration workflow, sometimes called "change-based migrations", allows each change to thedatabase schema to be checked-in to source control and reviewed during code-review. Users can still benefit from Atlasintelligently planning migrations for them, however they are not automatically applied.
To start, we will calculate the difference between thedesired andcurrent state of the database by running theatlas migrate diff
command.
To run this command, we need to provide the necessary parameters:
--dir
the URL to the migration directory, by default it isfile://migrations
.--to
the URL of the desired state. A state can be specified using a database URL, HCL or SQL schema, or another migration directory.--dev-url
a URL to aDev Database that will be used to compute the diff.
- Atlas DDL (HCL)
- SQL
atlas migratediff create_blog_posts\
--dir"file://migrations"\
--to"file://schema.hcl"\
--dev-url"docker://mysql/8/example"
atlas migratediff create_blog_posts\
--dir"file://migrations"\
--to"file://schema.sql"\
--dev-url"docker://mysql/8/example"
Runls migrations
, and you will notice that Atlas has created two files:
- 20220811074144_create_blog_posts.sql
- atlas.sum
-- create "blog_posts" table
CREATETABLE`example`.`blog_posts`(`id`intNOTNULL,`title`varchar(100)NULL,`body`textNULL,`author_id`intNULL,PRIMARYKEY(`id`),INDEX`author_id`(`author_id`),CONSTRAINT`author_fk`FOREIGNKEY(`author_id`)REFERENCES`example`.`users`(`id`))
In addition to the migration directory, Atlas maintains a file nameatlas.sum
which is usedto ensure the integrity of the migration directory and force developers to deal with situationswhere migration order or contents was modified after the fact.
h1:t1fEP1rSsGf1gYrYCjsGyEyuM0cnhATlq93B7h8uXxY=
20220811074144_create_blog_posts.sql h1:liZcCBbAn/HyBTqBAEVar9fJNKPTb2Eq+rEKZeCFC9M=
Now that we have our migration files ready, you can use themigrate apply
command to apply the changes to the database.To learn more about this process, check out theVersioned Migrations Quickstart Guide
Next Steps
In this short tutorial we learned how to use Atlas to inspect databases, as well as use declarative and versionedmigrations. Read more about the use-cases for the two approacheshere to help youdecide which workflow works best for you.
We have a super friendly#getting-started channel on our communitychat on Discord.
For web-based, free, and fun (GIFs included) support:
Join our Discord serverGet the latest Atlas tips and updates in our newsletter.