On this page
migrations
introduction
migrations are like version control for your database, allowing your team to define and share the application's database schema definition. if you have ever had to tell a teammate to manually add a column to their local database schema, you've faced the problem that database migrations solve.
each migration file is an es module that must export an asynchronous up function, and optionally a down function. the framework automatically injects a context object containing the Schema service, the table query builder, the raw db connection, and a query helper. these properties are also made available globally during the execution of the migration.
creating tables
to create a new database table, use the create method on the Schema facade. the create method accepts two arguments: the name of the table and a closure which receives a TableBuilder object used to define the new table.
1export async function up({ Schema }) {2 await Schema.create('users', table => {3 table.increments('id');4 table.string('name');5 table.string('email').unique();6 table.timestamps();7 });8}9 10export async function down({ Schema }) {11 await Schema.dropIfExists('users');12}
column types
the table builder contains a variety of column types that you may use when building your tables.
| type | description |
|---|---|
table.increments('id'); |
auto incrementing integer primary key |
table.bigIncrements('id'); |
auto incrementing big integer primary key |
table.integer('votes'); |
integer column |
table.bigInteger('views'); |
big integer column |
table.float('amount'); |
float column |
table.decimal('balance', '10,2'); |
decimal column with precision |
table.boolean('confirmed'); |
tinyint boolean column |
table.string('name', 100); |
varchar column with optional length |
table.text('description'); |
text column |
table.json('options'); |
json column |
table.enum('status', ['active', 'inactive']); |
enum column |
table.datetime('created_at'); |
datetime column |
table.date('birthday'); |
date column |
table.time('sunrise'); |
time column |
table.timestamps(); |
adds created_at and updated_at datetime columns |
column modifiers
in addition to the column types listed above, there are several column modifiers you may use while adding a column to a database table.
| Type | Description | |
|---|---|---|
table.string('email').nullable(); |
allows null values | |
table.string('title').notNullable(); |
prevents null values | |
table.integer('votes').unsigned(); |
makes integer unsigned | |
table.integer('status').defaultTo(1); |
sets default value | |
table.string('email').unique(); |
adds unique index | |
table.string('slug').index(); |
adds basic index | |
table.integer('id').primary(); |
explicitly adds primary key | |
table.string('status').comment('the user status'); |
adds column comment |
foreign keys
dframework supports adding foreign key constraints to your tables. you define the local column using the foreign method, specify the referenced column and table using the references method, and optionally define cascade rules.
1export async function up({ Schema }) {2 await Schema.create('posts', table => {3 table.increments('id');4 table.integer('user_id').unsigned();5 6 table.foreign('user_id')7 .references('id', 'users')8 .onDelete('cascade');9 });10}
modifying tables
the table method on the Schema facade allows you to update existing tables.
1export async function up({ Schema }) {2 await Schema.table('users', table => {3 table.string('phone').nullable();4 table.index('phone');5 });6}you can also rename an existing table using the rename method.
1await Schema.rename('old_table', 'new_table');
dropping tables
to drop an existing table, you may use the drop or dropIfExists methods.
1await Schema.drop('users');2await Schema.dropIfExists('users');
running migrations
the framework runs migrations sequentially in alphabetical order based on the filenames in your migrations directory. a database table named migrations is automatically generated to track which migrations have already been executed, organizing them into batches.
this ensures that only pending migrations are executed, avoiding duplicate table creations.
rolling back
if you need to revert the latest database changes, the framework allows you to roll back the most recent migration batch. it queries the migrations table to identify the last batch number and executes the down function for those specific files in reverse chronological order.

