Skip to main content

Quick Introduction

Atlas CLI is an open-source tool designed to help software engineers, DBAs and DevOps practitioners to manage their database schemas. Atlas users can use the Atlas DDL (data-definition language) to describe the desired database schema and use the command-line tool to plan and apply the migrations to their systems.

Installation

Get the latest release with Homebrew:

brew install ariga/tap/atlas

The binaries distributed in official releases are released under the Ariga End User License. If you would like to build Atlas from source follow the instructions here.

Start a local database container

For the purpose of this guide, we will start a local Docker container running MySQL.

docker run --name atlas-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=example mysql

For this example, we will start off with the following database:

CREATE table users (
id int PRIMARY KEY,
name varchar(100)
);

Our schema represents a users table, where each user has an ID and a name.

Inspecting our database

Atlas features a Data Definition Language (DDL) that has an HCL-syntax for defining the desired state of database schemas.

Inspection is done via the atlas schema inspect command.

To inspect our locally-running MySQL instance, use the -u flag and write the output to a file named schema.hcl:

atlas schema inspect -u "mysql://root:pass@localhost:3306/example" > schema.hcl

Open the schema.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 a table resource with id, and name columns. The schema field references the example schema that is defined elsewhere in this document. In addition, the primary_key sub-block defines the id column as the primary key for the table. Atlas strives to mimic the syntax of the database that the user is working against. In this case, the type for the id column is int, and varchar(100) for the name column.

Now, consider we want to add a blog_posts table and have our schema represent a simplified blogging system.

Blog ERD

Let's add the following to schema.hcl:

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]
}
index "author_id" {
unique = false
columns = [column.author_id]
}
}

In addition to the elements we saw in the users table, here we can find a foreign key block, declaring that the author_id column references the id column on the users table.

Now, let's apply these changes by running a migration. In Atlas, migrations can be applied in two types of workflows: declarative and versioned.

Declarative Migrations

The declarative approach requires the user to define the desired end schema, and Atlas provides a 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 the apply command:

atlas schema apply \
-u "mysql://root:pass@localhost:3306/example" \
-f schema.hcl

Atlas presents the plan it created by displaying the SQL statements. For example, for a MySQL database we will see the 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.

You can reinspect the database by running the inspect command again to ensure that the changes have been made to the schema.

Versioned Migrations

Alternatively, the versioned migration workflow, sometimes called "change-based migrations", allows each change to the database schema to be checked into source control and reviewed during code-review. Users can still benefit from Atlas intelligently planning migrations for them, however they are not automatically applied.

To start, we will calculate the difference between the desired and current state of the database by running the atlas migrate diff command.

To run this command, we need to provide the necessary parameters:

  • --dir the URL to the migration directory, by default it is file://migrations.
  • --to the URL of the desired state, an HCL file or a database connection.
  • --dev-url a URL to a Dev Database that will be used to compute the diff.
atlas migrate diff create_blog_posts \
--dir="file://migrations" \
--to="file://schema.hcl" \
--dev-url="mysql://root:pass@:3306/test"

Run ls migrations, and you will notice that Atlas has created two files:

-- 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`))

Now that we have our migration files ready, you can use your favorite migration tool to apply the changes generated by Atlas.

Next Steps

In this short tutorial we learned how to use Atlas to inspect databases, as well as use declarative and versioned migrations. Read more about the use-cases for the two approaches here to help you decide which workflow works best for you.

Need help getting started?

We have a super friendly #getting-started channel on our community chat on Discord.

For web-based, free, and fun (GIFs included) support:

Join our Discord server