Declarative SQL database schema management by human-friendly pure SQL.
- 100% pure SQL schema file
- Diff visualization between a schema file and actual database schemas
- Automatic generation and execution of ALTER statements to apply the schema
- No need to "import" redundant schemas from the database: write your own way
- MySQL (8.x, 5.x)
brew tap kota65535/alternator
brew install alternator
Download the binary from GitHub Releases and drop it in
your $PATH
.
- Create a schema file. As an example here, we create
schema.sql
with the following content.
CREATE DATABASE example;
USE example;
CREATE TABLE users
(
id int PRIMARY KEY,
name varchar(100)
);
CREATE TABLE blog_posts
(
id int PRIMARY KEY,
title varchar(100),
body text,
author_id int,
FOREIGN KEY (author_id) REFERENCES users (id)
);
- Run the schema file to create a database and tables.
mysql -u root < schema.sql
- Run
alternator plan
to verify the schema is up-to-date.
alternator plan schema.sql mysql://root@localhost/example
Show Output
Fetching schemas of database 'example'...
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Schema diff:
CREATE DATABASE `example`;
CREATE TABLE `example`.`users`
(
`id` int NOT NULL,
`name` varchar(100),
PRIMARY KEY (`id`)
);
CREATE TABLE `example`.`blog_posts`
(
`id` int NOT NULL,
`title` varchar(100),
`body` text,
`author_id` int,
PRIMARY KEY (`id`),
CONSTRAINT `blog_posts_ibfk_1` FOREIGN KEY `author_id` (`author_id`) REFERENCES `users` (`id`)
);
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Your database schema is up-to-date! No change required.
- Now let's modify the schema file.
CREATE DATABASE example;
USE example;
CREATE TABLE users
(
id int PRIMARY KEY AUTO_INCREMENT, # add AUTO_INCREMENT
name varchar(100),
INDEX (name) # added
);
CREATE TABLE blog_posts
(
id int PRIMARY KEY,
title varchar(200), # modify length 100 -> 200
content text, # rename body -> content
author_id int,
FOREIGN KEY (author_id) REFERENCES users (id)
);
CREATE TABLE categories # added
(
id int PRIMARY KEY,
name varchar(100)
);
- Run
alternator plan
to show the schema diff and SQL statements that should be executed. Note that the foreign keyauthor_id
should be recreated because of the modification of the referencing key.
alternator plan schema.sql mysql://root@localhost/example
Show Output
Fetching schemas of database 'example'...
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Schema diff:
CREATE DATABASE `example`;
CREATE TABLE `example`.`users`
(
! `id` int NOT NULL -> `id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100),
PRIMARY KEY (`id`),
+ INDEX (`name`)
);
CREATE TABLE `example`.`blog_posts`
(
`id` int NOT NULL,
! `title` varchar(100) -> `title` varchar(200),
! `body` text -> `content` text,
`author_id` int,
PRIMARY KEY (`id`),
- CONSTRAINT `blog_posts_ibfk_1` FOREIGN KEY `author_id` (`author_id`) REFERENCES `users` (`id`),
+ FOREIGN KEY (author_id) REFERENCES users (id)
);
+ CREATE TABLE `example`.`categories`
+ (
+ `id` int NOT NULL,
+ `name` varchar(100),
+ PRIMARY KEY (`id`)
+ );
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Statements to execute:
ALTER TABLE `example`.`users` ADD INDEX (`name`);
ALTER TABLE `example`.`blog_posts` MODIFY COLUMN `title` varchar(200);
ALTER TABLE `example`.`blog_posts` CHANGE COLUMN `body` `content` text;
ALTER TABLE `example`.`blog_posts` DROP FOREIGN KEY `blog_posts_ibfk_1`;
ALTER TABLE `example`.`blog_posts` DROP INDEX `author_id`;
ALTER TABLE `example`.`users` MODIFY COLUMN `id` int NOT NULL AUTO_INCREMENT;
ALTER TABLE `example`.`blog_posts` ADD FOREIGN KEY (`author_id`) REFERENCES `users` (`id`);
CREATE TABLE `example`.`categories`
(
`id` int NOT NULL,
`name` varchar(100),
PRIMARY KEY (`id`)
);
- Run
alternator apply
to apply the schema change by executing planned SQL statements.
alternator apply schema.sql mysql://root@localhost/example
Show Output
Fetching schemas of database 'example'...
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Statements to execute:
ALTER TABLE `example`.`users` ADD INDEX (`name`);
ALTER TABLE `example`.`blog_posts` MODIFY COLUMN `title` varchar(200);
ALTER TABLE `example`.`blog_posts` CHANGE COLUMN `body` `content` text;
ALTER TABLE `example`.`blog_posts` DROP FOREIGN KEY `blog_posts_ibfk_1`;
ALTER TABLE `example`.`blog_posts` DROP INDEX `author_id`;
ALTER TABLE `example`.`users` MODIFY COLUMN `id` int NOT NULL AUTO_INCREMENT;
ALTER TABLE `example`.`blog_posts` ADD FOREIGN KEY (`author_id`) REFERENCES `users` (`id`);
CREATE TABLE `example`.`categories`
(
`id` int NOT NULL,
`name` varchar(100),
PRIMARY KEY (`id`)
);
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Do you want to apply? [y/n]: y
Executing: ALTER TABLE `example`.`users` ADD INDEX (`name`);
Executing: ALTER TABLE `example`.`blog_posts` MODIFY COLUMN `title` varchar(200);
Executing: ALTER TABLE `example`.`blog_posts` CHANGE COLUMN `body` `content` text;
Executing: ALTER TABLE `example`.`blog_posts` DROP FOREIGN KEY `blog_posts_ibfk_1`;
Executing: ALTER TABLE `example`.`blog_posts` DROP INDEX `author_id`;
Executing: ALTER TABLE `example`.`users` MODIFY COLUMN `id` int NOT NULL AUTO_INCREMENT;
Executing: ALTER TABLE `example`.`blog_posts` ADD FOREIGN KEY (`author_id`) REFERENCES `users` (`id`);
Executing: CREATE TABLE `example`.`categories`
(
`id` int NOT NULL,
`name` varchar(100),
PRIMARY KEY (`id`)
);
Finished!