Introduction
Lotus v0.4.0 (Jun 23) will ship a really useful feature: database migrations.
It's a really fast way to manage database schema via Ruby. For a detailed explanation of the feature, please have a look at the related pull requests.
Command Line
Here's new CLI facilities to control database schema.
% lotus new bookshelf --database=postgres && cd bookshelf && bundle
% lotus db
Commands:
lotus db apply # migrate, dump schema, delete migrations (experimental)
lotus db console # start DB console
lotus db create # create database for current environment
lotus db drop # drop database for current environment
lotus db help [COMMAND] # Describe subcommands or one specific subcommand
lotus db migrate # migrate database for current environment
lotus db prepare # create and migrate database
lotus db version # current database version
These commands modify the database for the current environnment.
There are some safety mechanisms, for instance db drop
will raise an error if ran in production mode.
Migration Generator
This upcoming version will ship with a migration generator.
% lotus generate migration create_books
create db/migrations/20150617145519_create_books.rb
Let's edit it:
Lotus::Model.migration do
change do
create_table :books do
primary_key :id
foreign_key :author_id, :authors, on_delete: :cascade, null: false
column :code, String, null: false, unique: true, size: 128
column :title, String, null: false
column :price, Integer, null: false, default: 100 # cents
check { price > 0 }
end
end
end
We use a create_table
block to define the schema of that table.
The first line is primary_key :id
, which is a shortcut to create an autoincrement integer column.
There is a foreign key definition with cascade deletion.
The first argument is the name of the local column (books.author_id
), while the second is the referenced table.
Then we have three lines for columns.
The first argument that we pass to #column
is the name, then the type.
The type can be a Ruby type such as String
or Integer
or a string that represent the native database type (eg. "varchar(32)"
or "text[]"
).
As a last optional argument there is a Hash that specify some extra details for the column. For instance NULL or uniqueness constraints, the size (for strings) or the default value.
The final line defines a database check to ensure that price will always be greater than zero.
Migrate
As first thing we need to create the database and then we can modify the schema.
% lotus db create
% lotus db migrate
When we run db migrate
, it applies all the pending migrations under db/migrations
.
Our books
table is now created. We can ask our application what's the current schema version.
% lotus db version
20150617145519
In case we want to target a specific database version, we can pass it as extra argument to db migrate
.
This is useful if we want to partially migrate the database, or rollback some changes.
For instance, if we recognize an error in our just created migration, we can do:
% lotus db migrate 0 # get back to the initial version
% vim db/migrations/20150617145519_create_books.rb
% lotus db migrate # run all the pending migrations again
Prepare
We're fan of system automation, for this reason we have added a new command to get our database ready for development, tests or CI: db prepare
.
It performs the following operations:
- Creates database
- Load schema structure, if present (see next section, Apply).
- Runs pending migrations
If used with db apply
it's really fast and it should be the preferred way to setup databases.
Apply
When an application is developed for years, it accumulates dozens or hundreds of migrations. This slows down database operations for development and tests (CI).
We have introduced an experimental feature: db apply
.
By running this command, it:
- Runs pending migrations
- Dumps schema informations into
db/schema.sql
- Deletes all the migrations from
db/migrations
% lotus db apply
% tree db/migrations
0 directories, 0 files
Release Date
Database migrations will be available with lotusrb-0.4.0
, expected for June 23, 2015.