What the F*ck Is With All the Artisan Commands: migrate
Now that we’ve learned how to create our migrations it’s time to discuss how to work with them using the migrate
family of commands.
Why It Exists
As we discussed in our previous article, database migrations allow you to define changes to your database so you can easily apply the changes everywhere you maintain a copy of the database for the application. The migrate
family of commands gives us control over applying those migrations to the database.
When Should You Use It
Any time you’re editing the structure of a table.
Overview
As a quick review here’s what the migrate
family of commands looks like in the help display.
migrate
migrate:fresh Drop all tables and re-run all migrations
migrate:install Create the migration repository
migrate:refresh Reset and re-run all migrations
migrate:reset Rollback all database migrations
migrate:rollback Rollback the last database migration
migrate:status Show the status of each migration
migrate:install
The migrate:install
command creates the “migrations” table inside the database. This table is used to keep track of the migrations that have been run against the database. I’m guessing this command exists as a form of completionism because some of the commands below automatically create this table when it’s missing.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:install
Migration table created successfully.
The migrations table itself is super simple:
mysql> show columns from migrations;
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| migration | varchar(255) | NO | | NULL | |
| batch | int(11) | NO | | NULL | |
+-----------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
migrate:status
The migrate:status
command displays the status all the migrations you have defined.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 2 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 3 |
| No | 2019_10_11_011555_create_tasks_table | |
+------+------------------------------------------------+-------+
The main items to highlight here are:
- The “Ran?” column which display if the migration has been run against the current database
- The “Migration” column which displays the name of the migration
- The “Batch” column which displays in what order the migrations were run.
In the example above I ran the first three migrations separately but if I had run them at the same time I would have ended up with with the results below.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 1 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 1 |
| No | 2019_10_11_011555_create_tasks_table | |
+------+------------------------------------------------+-------+
migrate
The migrate
command runs any migrations that have not been run against the database. It uses the up()
function inside the migration to determine what to do.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate
Migrating: 2019_10_11_011555_create_tasks_table
Migrated: 2019_10_11_011555_create_tasks_table (0.08 seconds)
Now if we look at the current status we’ll see that “2019_10_11_011555_create_tasks_table” was applied in it’s own batch.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 2 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 3 |
| Yes | 2019_10_11_011555_create_tasks_table | 4 |
+------+------------------------------------------------+-------+
migrate:rollback
The migrate:rollback
command takes the list of migrations in the last batch number and runs their down()
function.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:rollback
Rolling back: 2019_10_11_011555_create_tasks_table
Rolled back: 2019_10_11_011555_create_tasks_table (0.02 seconds)
Now we can look at the status and see that “2019_10_11_011555_create_tasks_table” is no longer listed as being run.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 2 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 3 |
| No | 2019_10_11_011555_create_tasks_table | |
+------+------------------------------------------------+-------+
migrate:fresh
The migrate:fresh
command deletes all existing tables and then runs all the migrations.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:fresh
Dropped all tables successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.09 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.04 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Migrating: 2019_10_11_011555_create_tasks_table
Migrated: 2019_10_11_011555_create_tasks_table (0.03 seconds)
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 1 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 1 |
| Yes | 2019_10_11_011555_create_tasks_table | 1 |
+------+------------------------------------------------+-------+
Be careful with this command. “Dropped all tables successfully” includes any tables that aren’t being managed by the migrations. We’re in the process of migrating to Laravel and running php artisan migrate:fresh
deleted all the tables that we hadn’t created using Laravel migrations. Thank goodness it was on a development VM. :-)
migrate:refresh
The migrate:refresh
command rolls back all the migrations and then runs them again.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:refresh
Rolling back: 2019_10_11_011555_create_tasks_table
Rolled back: 2019_10_11_011555_create_tasks_table (0.01 seconds)
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_100000_create_password_resets_table (0.02 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table (0.01 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.03 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Migrating: 2019_10_11_011555_create_tasks_table
Migrated: 2019_10_11_011555_create_tasks_table (0.05 seconds)
Now if we look at our migration status we’ll see everything was applied in one big batch.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| Yes | 2014_10_12_000000_create_users_table | 1 |
| Yes | 2014_10_12_100000_create_password_resets_table | 1 |
| Yes | 2019_08_19_000000_create_failed_jobs_table | 1 |
| Yes | 2019_10_11_011555_create_tasks_table | 1 |
+------+------------------------------------------------+-------+
migrate:reset
The migrate:reset
command rolls back all the migrations and then stops.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:reset
Rolling back: 2019_10_11_011555_create_tasks_table
Rolled back: 2019_10_11_011555_create_tasks_table (0.02 seconds)
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back: 2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_100000_create_password_resets_table (0 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table (0 seconds)
If we look at migrate:status
now, none of the migrations have been run.
ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:status
+------+------------------------------------------------+-------+
| Ran? | Migration | Batch |
+------+------------------------------------------------+-------+
| No | 2014_10_12_000000_create_users_table | |
| No | 2014_10_12_100000_create_password_resets_table | |
| No | 2019_08_19_000000_create_failed_jobs_table | |
| No | 2019_10_11_011555_create_tasks_table | |
+------+------------------------------------------------+-------+
When Do I Use These Commands?
status
,migrate
androllback
are the bread and butter of this family of functions. You’ll be using them all the time.fresh
andrefresh
are used if you need to reset your database to a clean state.reset
is a mystery to me. I can’t think of any good reason you would want to rollback every migration and then stop. Sound off in the comments if you have an explanation.
Hopefully this has been as helpful to you as it has to me and check back soon for more artisan commands.
Scott Keck-Warren
Scott is the Director of Technology at WeCare Connect where he strives to provide solutions for his customers needs. He's the father of two and can be found most weekends working on projects around the house with his loving partner.
Top Posts
- Working With Soft Deletes in Laravel (By Example)
- Fixing CMake was unable to find a build program corresponding to "Unix Makefiles"
- Upgrading to Laravel 8.x
- Get The Count of the Number of Users in an AD Group
- Multiple Vagrant VMs in One Vagrantfile
- Fixing the "this is larger than GitHub's recommended maximum file size of 50.00 MB" error
- Changing the Directory Vagrant Stores the VMs In
- Accepting Android SDK Licenses From The OSX Command Line
- Fixing the 'Target class [config] does not exist' Error
- Using Rectangle to Manage MacOS Windows