Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Migrations

A migration is a file describing a change to the database structure: create a table, add a column, drop an index. Migrations live in the project together with the code, so every developer and the server end up with the same database. They work like migrations in Laravel.

Creating a migration

node ace make:migration posts

A file like 1727950000000_create_posts_table.ts appears in database/migrations/. The number at the start is the creation time: migrations run in that order.

Describing a table

Open the file and describe the post columns:

// database/migrations/1727950000000_create_posts_table.ts
import { BaseSchema } from '@adonisjs/lucid/schema'
 
export default class extends BaseSchema {
  protected tableName = 'posts'
 
  async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.increments('id')
      table.string('title').notNullable()
      table.text('body').notNullable()
      table.boolean('is_published').defaultTo(false)
      table.timestamp('created_at')
      table.timestamp('updated_at')
    })
  }
 
  async down() {
    this.schema.dropTable(this.tableName)
  }
}

The up method applies the change, and down reverts it. Column names in the database are written in snake_case.

Column types

MethodColumn
increments('id')Auto-increment primary key
string('title')A string up to 255 characters
text('body')Long text
integer('views')An integer
boolean('is_published')Yes or no
timestamp('created_at')Date and time

Modifiers are chained: notNullable(), nullable(), defaultTo(0), unique().

Running them

node ace migration:run

Lucid runs up for all new migrations and records them in the service table adonis_schema. The terminal shows the line migrated database/migrations/..._create_posts_table.

CommandWhat it does
migration:runApplies new migrations
migration:rollbackRolls back the last batch
migration:statusShows which migrations are applied
migration:freshDrops all tables and applies the migrations again

Changing a table

To add a column to an existing table, create a new migration and use alterTable:

node ace make:migration add_slug_to_posts
// database/migrations/1727960000000_add_slug_to_posts.ts
import { BaseSchema } from '@adonisjs/lucid/schema'
 
export default class extends BaseSchema {
  protected tableName = 'posts'
 
  async up() {
    this.schema.alterTable(this.tableName, (table) => {
      table.string('slug').nullable().unique()
    })
  }
 
  async down() {
    this.schema.alterTable(this.tableName, (table) => {
      table.dropColumn('slug')
    })
  }
}

After node ace migration:run the posts table has a slug column.

Common mistake

Editing a migration that has already run changes nothing: Lucid sees it in adonis_schema and does not run it again. While the project is only on your machine, you can roll it back with migration:rollback, fix it and apply it again. If the migration has already reached the server or your colleagues, leave it alone and create a new one.

Thanks for reading!

Donate to the site — we work hard for you.