What is Laravel Migrations?
In Laravel, Migrations offer a file-based approach to changing the structure of your database, allowing you to create and drop tables, add, update and delete columns, and add indexes, among other tasks. Further, you can easily revert, or roll back, any changes if a mistake has been made or you otherwise reconsider the decision. Finally, because each migration is stored in a text file, you can manage them within your project repository.
Install Laravel Migration Table
To creates the database Migratin table that keeps track of which migrations you have and haven’t run; this is run automatically when you run your migrations.
php artisan migrate:install
See the example:
Now you can see migration table already created in your database:
Create New Laravel Migration File
To create a new migration file with model, use the make:model migration_file_name -m
Artisan command:
php artisan make:model users -m
Lets See the output
There are two flags you can optionally pass to this command. --create=table_name
prefills the migration with code designed to create a table named table_name, and --table=_table_name_ just
prefills the migration for modifications to an existing table. Here are a few examples:
Defining Laravel Migrations
A migration is a single file that defines two things: the modifications desired when running this migration up and the modifications desired when running this migration down.
“Up” and “Down” in Migrations
Migrations are always run in order by date. Every migration file is named something like this: 2014_10_12_000000_create_users_table.php located at database/migrations folder. When a new system is migrated,the system grabs each migration, starting at the earliest date, and runs its up() method—you’re migrating it “up” at this point. But the migration system also allows you to “roll back” your most recent set of migrations. It’ll grab each of them and run its down() method, which should undo whatever changes the up migration made. So, the up() method of a migration should “do” its migration, and the down() method should “undo” it.
So Let’s see our “create_users_table” migration that looks like.
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->string('name'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
Configure Laravel Database
To work with laravel migration, first you need to connect your database in Laravel, you can utilizes the .env PHP library by Vance Lucas. In a fresh Laravel installation, the root directory of your application will contain a .env.example file. If you install Laravel via Composer, this file will automatically be renamed to .env. Otherwise, you should rename the file manually.
Creating tables
We already saw in ourcreate_users_table
migration that our migrations depend on the Schema facade and its methods. Everything we can do in these migrations will rely on the methods of Schema. To create a new table in a migration, use the create() method—the first parameter is the table name, and the second is a closure that defines its columns:
Schema::create('tablename', function (Blueprint $table) { // Create columns here });
Dropping tables
If you want to drop a table, there’s a drop method on Schema that takes one parameter,the table name:
Schema::drop('users');
Creating columns
To create new columns in a table, whether in a create table call or a modify table call,use the instance of Blueprint that’s passed into your closure:
Schema::create('users', function (Blueprint $table) { $table->string('name'); });
Let’s look at the various methods available on Blueprint instances for creating columns. I’ll describe how they work in MySQL, but if you’re using another database, Laravel will just use the closest equivalent.
Running Laravel Migrations
To run all of your outstanding migrations, execute the migrate Artisan command:
php artisan migrate
See the Output:
Migration Insert Data
We already create an users table and add 33 seed records using Faker Library. Open/database/migrations/2017_03_05_073454_create_users_table.php.
Add the following code:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->string('name'); }); $faker = Faker\Factory::create(); $limit = 33; for ($i = 0; $i < $limit; $i++) { DB::table('users')->insert([ //, 'name' => $faker->name, ]); } } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
HERE,
$faker = Faker\Factory::create(); creates an instance of Faker factory
$limit = 33; sets the number of records that we want to add to the database.
for ($i = 0; $i < $limit; $i++) { DB::table('users')->insert([…]);} uses a for loop to add records to the database 33 times. $faker->name generates a faker name
Run the following command to run the migration
php artisan migrate:refresh
You will get the following message
And See The Output:
Forcing Migrations To Run In Production
Some migration operations are destructive, which means they may cause you to lose data. In order to protect you from running these commands against your production database, you will be prompted for confirmation before the commands are executed. To force the commands to run without a prompt, use the --force flag:
php artisan migrate --force
Rolling Back Migrations
To rollback the latest migration operation, you may use the rollback command. This command rolls back the last “batch” of migrations, which may include multiple migration files:
php artisan migrate:rollback
You may rollback a limited number of migrations by providing the step option to the rollback command. For example, the following command will rollback the last five migrations:
php artisan migrate:rollback --step=5
The migrate:reset command will roll back all of your application’s migrations:
php artisan migrate:reset
Rollback & Migrate In Single Command
The migrate:refresh command will roll back all of your migrations and then execute the migrate command. This command effectively re-creates your entire database:
php artisan migrate:refresh
// Refresh the database and run all database seeds…
php artisan migrate:refresh --seed
You may rollback & re-migrate a limited number of migrations by providing the step option to the refresh command. For example, the following command will rollback & re-migrate the last five migrations:
php artisan migrate:refresh --step=5
Migration Add Column / Drop Colum
If you want to add a new column to users table for email. You want to add the new column after the name field.
Run the following command
php artisan make:migration add_email_to_users --table=users
HERE
--table=users
tells Laravel you want to work with an existing table called users
Lets see Output:
Open the new migration file in /database/migration/2017_03_09_101140_add_email_to_users.php
Modify it to the following
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddEmailToUsers extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('email')->after('name'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('email'); }); } }
HERE,
public function up(){…} uses Schema::table(‘users’…) to add a new column email
public function down(){…} drops the new column from the table when we reverse the command. $table->dropColumn(’email’); is the command that drops the table.
Available Column Types
Of course, the schema builder contains a variety of column types that you may specify when building your tables:
Command | Description |
---|---|
$table->bigIncrements('id'); |
Incrementing ID (primary key) using a "UNSIGNED BIG INTEGER" equivalent. |
$table->bigInteger('votes'); |
BIGINT equivalent for the database. |
$table->binary('data'); |
BLOB equivalent for the database. |
$table->boolean('confirmed'); |
BOOLEAN equivalent for the database. |
$table->char('name', 4); |
CHAR equivalent with a length. |
$table->date('created_at'); |
DATE equivalent for the database. |
$table->dateTime('created_at'); |
DATETIME equivalent for the database. |
$table->dateTimeTz('created_at'); |
DATETIME (with timezone) equivalent for the database. |
$table->decimal('amount', 5, 2); |
DECIMAL equivalent with a precision and scale. |
$table->double('column', 15, 8); |
DOUBLE equivalent with precision, 15 digits in total and 8 after the decimal point. |
$table->enum('choices', ['foo', 'bar']); |
ENUM equivalent for the database. |
$table->float('amount', 8, 2); |
FLOAT equivalent for the database, 8 digits in total and 2 after the decimal point. |
$table->increments('id'); |
Incrementing ID (primary key) using a "UNSIGNED INTEGER" equivalent. |
$table->integer('votes'); |
INTEGER equivalent for the database. |
$table->ipAddress('visitor'); |
IP address equivalent for the database. |
$table->json('options'); |
JSON equivalent for the database. |
$table->jsonb('options'); |
JSONB equivalent for the database. |
$table->longText('description'); |
LONGTEXT equivalent for the database. |
$table->macAddress('device'); |
MAC address equivalent for the database. |
$table->mediumIncrements('id'); |
Incrementing ID (primary key) using a "UNSIGNED MEDIUM INTEGER" equivalent. |
$table->mediumInteger('numbers'); |
MEDIUMINT equivalent for the database. |
$table->mediumText('description'); |
MEDIUMTEXT equivalent for the database. |
$table->morphs('taggable'); |
Adds unsigned INTEGER taggable_id and STRING taggable_type . |
$table->nullableMorphs('taggable'); |
Nullable versions of the morphs() columns. |
$table->nullableTimestamps(); |
Nullable versions of the timestamps() columns. |
$table->rememberToken(); |
Adds remember_token as VARCHAR(100) NULL. |
$table->smallIncrements('id'); |
Incrementing ID (primary key) using a "UNSIGNED SMALL INTEGER" equivalent. |
$table->smallInteger('votes'); |
SMALLINT equivalent for the database. |
$table->softDeletes(); |
Adds nullable deleted_at column for soft deletes. |
$table->string('email'); |
VARCHAR equivalent column. |
$table->string('name', 100); |
VARCHAR equivalent with a length. |
$table->text('description'); |
TEXT equivalent for the database. |
$table->time('sunrise'); |
TIME equivalent for the database. |
$table->timeTz('sunrise'); |
TIME (with timezone) equivalent for the database. |
$table->tinyInteger('numbers'); |
TINYINT equivalent for the database. |
$table->timestamp('added_on'); |
TIMESTAMP equivalent for the database. |
$table->timestampTz('added_on'); |
TIMESTAMP (with timezone) equivalent for the database. |
$table->timestamps(); |
Adds nullable created_at and updated_at columns. |
$table->timestampsTz(); |
Adds nullable created_at and updated_at (with timezone) columns. |
$table->unsignedBigInteger('votes'); |
Unsigned BIGINT equivalent for the database. |
$table->unsignedInteger('votes'); |
Unsigned INT equivalent for the database. |
$table->unsignedMediumInteger('votes'); |
Unsigned MEDIUMINT equivalent for the database. |
$table->unsignedSmallInteger('votes'); |
Unsigned SMALLINT equivalent for the database. |
$table->unsignedTinyInteger('votes'); |
Unsigned TINYINT equivalent for the database. |
$table->uuid('id'); |
UUID equivalent for the database. |
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. For example, to make the column "nullable", you may use the nullable
method:
Schema::table('users', function (Blueprint $table) { $table->string('email')->nullable(); });
Below is a list of all the available column modifiers. This list does not include the index modifiers:
Modifier | Description |
---|---|
->after('column') |
Place the column "after" another column (MySQL Only) |
->comment('my comment') |
Add a comment to a column |
->default($value) |
Specify a "default" value for the column |
->first() |
Place the column "first" in the table (MySQL Only) |
->nullable() |
Allow NULL values to be inserted into the column |
->storedAs($expression) |
Create a stored generated column (MySQL Only) |
->unsigned() |
Set integer columns to UNSIGNED |
->virtualAs($expression) |
Create a virtual generated column (MySQL Only) |
Modifying Columns
Prerequisites
Before modifying a column, be sure to add the doctrine/dbal
dependency to your composer.json
file. The Doctrine DBAL library is used to determine the current state of the column and create the SQL queries needed to make the specified adjustments to the column:
composer require doctrine/dbal
Updating Column Attributes
The change
method allows you to modify some existing column types to a new type or modify the column's attributes. For example, you may wish to increase the size of a string column. To see the change
method in action, let's increase the size of the name
column from 25 to 50:
Schema::table('users', function (Blueprint $table) { $table->string('name', 50)->change(); });
We could also modify a column to be nullable:
Schema::table('users', function (Blueprint $table) { $table->string('name', 50)->nullable()->change(); });
Renaming Columns
To rename a column, you may use the renameColumn
method on the Schema builder. Before renaming a column, be sure to add the doctrine/dbal
dependency to your composer.json
file:
Schema::table('users', function (Blueprint $table) { $table->renameColumn('from', 'to'); });
Dropping Columns
To drop a column, use the dropColumn
method on the Schema builder. Before dropping columns from a SQLite database, you will need to add the doctrine/dbal
dependency to your composer.json
file and run the composer update
command in your terminal to install the library:
Schema::table('users', function (Blueprint $table) { $table->dropColumn('votes'); });
You may drop multiple columns from a table by passing an array of column names to the dropColumn
method:
Schema::table('users', function (Blueprint $table) { $table->dropColumn(['votes', 'avatar', 'location']); });
Creating Indexes
The schema builder supports several types of indexes. First, let's look at an example that specifies a column's values should be unique. To create the index, we can simply chain the unique
method onto the column definition:
$table->string('email')->unique();
Alternatively, you may create the index after defining the column. For example:
$table->unique('email');
You may even pass an array of columns to an index method to create a compound index:
$table->index(['account_id', 'created_at']);
Laravel will automatically generate a reasonable index name, but you may pass a second argument to the method to specify the name yourself:
$table->index('email', 'my_index_name');
Available Index Types
Command | Description |
---|---|
$table->primary('id'); |
Add a primary key. |
$table->primary(['first', 'last']); |
Add composite keys. |
$table->unique('email'); |
Add a unique index. |
$table->unique('state', 'my_index_name'); |
Add a custom index name. |
$table->unique(['first', 'last']); |
Add a composite unique index. |
$table->index('state'); |
Add a basic index. |
Index Lengths & MySQL / MariaDB
Laravel uses the utf8mb4
character set by default, which includes support for storing "emojis" in the database. If you are running a version of MySQL older than the 5.7.7 release or MariaDB older than the 10.2.2 release, you may need to manually configure the default string length generated by migrations in order for MySQL to create indexes for them. You may configure this by calling the Schema::defaultStringLength
method within your AppServiceProvider
:
use Illuminate\Support\Facades\Schema; /** * Bootstrap any application services. * * @return void */ public function boot() { Schema::defaultStringLength(191); }
Alternatively, you may enable the innodb_large_prefix
option for your database. Refer to your database's documentation for instructions on how to properly enable this option.
Dropping Indexes
To drop an index, you must specify the index's name. By default, Laravel automatically assigns a reasonable name to the indexes. Simply concatenate the table name, the name of the indexed column, and the index type. Here are some examples:
Command | Description |
---|---|
$table->dropPrimary('users_id_primary'); |
Drop a primary key from the "users" table. |
$table->dropUnique('users_email_unique'); |
Drop a unique index from the "users" table. |
$table->dropIndex('geo_state_index'); |
Drop a basic index from the "geo" table. |
If you pass an array of columns into a method that drops indexes, the conventional index name will be generated based on the table name, columns and key type:
Schema::table('geo', function (Blueprint $table) { $table->dropIndex(['state']); // Drops index 'geo_state_index' });
Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I’m a Certified Engineer on ZEND PHP 5.3, I served my first five years a number of leadership positions at Winux Soft Ltd, SSL Wireless Ltd, Canadian International Development Agency (CIDA), World Vision, Care Bangladesh, Helen Keller, US AID and MAX Group where I worked on ERP software and web development., but now i’m a founder and CEO of TechBeeo Software Company Ltd. I’m also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute – a leading Training Institute in the country.
comprehensive articel