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 postsA 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
| Method | Column |
|---|---|
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:runLucid 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.
| Command | What it does |
|---|---|
migration:run | Applies new migrations |
migration:rollback | Rolls back the last batch |
migration:status | Shows which migrations are applied |
migration:fresh | Drops 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.