This page looks best with JavaScript enabled

Manage incremental changes to database in AdonisJS

 ·   ·  ☕ 2 min read

Use database migration utilities in Adonis to its complete potential. Carry out incremental updates - may it be a new table, or changes to existing table using distinct migration files that are version controlled.

You have a beautiful Todo application that has a todos table with the following columns:

  • description
  • status
  • end_date

Now, let’s say our users ask for a new field called planned_end_date.

Your first instinct may be to add the column to the database, change controller code if required, and call it a day. But, what if you to start making changes at different times to -

  • create a related entity called todo sub-items on 3-Jan
  • add target_end_date on 4-Jan
  • add remarks column on 15-Jan
  • add pre-default value to target_end_date on 26-Jan

The point is that there may be tens or hundreds of changes to be deployed to your target environment. It is quite easy to get lost in the details and not track all the changes that needs to be done in a higher environment.

That’s where Adonis migration files save significant effort and time, and make the whole migration process efficient.

In the above example of todos table: the first migration file will look like this -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"use strict";

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use("Schema");

class TodoSchema extends Schema {
  up() {
    this.create("todos", (table) => {
      table.increments();
      table.timestamps();

      table.string("description");
      table.string("status");
      table.datetime("date");
    });
  }

  down() {
    this.drop("todos");
  }
}

module.exports = TodoSchema;

When the changes start pouring in, you don’t make changes in the database or in the same file. Instead you create a new file - todo_schema_4Jan.js.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//todo_schema_4Jan.js

"use strict";

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use("Schema");

class TodoSchema extends Schema {
  up() {
    this.table("todos", (table) => {
      table.datetime("end_date");
    });
  }

  down() {}
}

module.exports = TodoSchema;

I have not provided anything in down method but you could potentially drop newly created columns in the same file.

Apply changes to the database in dev/higher environments -

1
adonis migration:run

Repeat the process for other fields as changes come through.

There are several advantages in following this process -

  1. Complete clarity on schema changes to the entire development team
  2. Catch all changes to the schema. All files are version controlled
  3. Apply or rollback changes with ease. Everything is controlled through code
Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things