Laravel Migration Generator

generate migrations from existing database

In this tutorial, we’ll work with a Laravel Migration Generator. When generating our migrations, it can sometimes be a bit confusing as to the correct way to add columns or fields to our tables. There are a large amount of methods to use within the Schema and Blueprint classes to wrap our heads around. Many times, you might even have a database in place, but you would like to move this instance to another host, or simply have a blueprint of the database in a set of migration files. Wouldn’t it be great if we had a way to handle doing this for us automatically? In fact we do now thanks to the work of barryvdh and now Xethron. Let’s see how to put this in action.


Configure Your Laravel Environment

  • Step 1. The first thing we will do for this is to install the needed dependencies into our composer.json file. Per the instructions at the Xethron github page, we can set up our composer.json file to pull in what we need. There are a few snippets at the prior link, here is the entirety of the composer.json file used in this testing demo.
    {
    	"name": "laravel/laravel",
    	"description": "The Laravel Framework.",
    	"keywords": ["framework", "laravel"],
    	"license": "MIT",
    	"type": "project",
    	"repositories": [
        {
            "type": "git",
            "url": "git@github.com:jamisonvalenta/Laravel-4-Generators.git"
        }
        ],
    	"require": {
    		"laravel/framework": "5.0.*",
    		"laravel/socialite": "~2.0"
    
    	},
    	"require-dev": {
    		"phpunit/phpunit": "~4.0",
    		"phpspec/phpspec": "~2.1",
    		"xethron/migrations-generator": "dev-l5",
                    "way/generators": "dev-feature/laravel-five-stable"
    	},
    	"autoload": {
    		"classmap": [
    			"database"
    		],
    		"psr-4": {
    			"App\\": "app/"
    		}
    	},
    	"autoload-dev": {
    		"classmap": [
    			"tests/TestCase.php"
    		]
    	},
    	"scripts": {
    		"post-install-cmd": [
    			"php artisan clear-compiled",
    			"php artisan optimize"
    		],
    		"post-update-cmd": [
    			"php artisan clear-compiled",
    			"php artisan optimize"
    		],
    		"post-create-project-cmd": [
    			"php -r \"copy('.env.example', '.env');\"",
    			"php artisan key:generate"
    		]
    	},
    	"config": {
    		"preferred-install": "dist"
    	}
    }
    
  • Step 2. Next up, we need to simply run a composer update. At the terminal, simply type composer update then hit enter.
  • Step 3. Add the following to the providers array in app.php
    
    'Way\Generators\GeneratorsServiceProvider',
    'Xethron\MigrationsGenerator\MigrationsGeneratorServiceProvider',
    
  • Step 4. Configure the .env file to point to the local database that has the tables you want to create migrations for. In this example, we’ll point Laravel at a WordPress database for a common example.
  • Step 5. Run the migrate commands and prosper!
vagrant@homestead:~$ `php artisan migrate:generate`
Using connection: mysql

Generating migrations for: wp_commentmeta, wp_comments, wp_links, wp_options, wp_postmeta, wp_posts, wp_term_relationships, wp_term_taxonomy, wp_terms
, wp_usermeta, wp_users
Do you want to log these migrations in the migrations table? [Y/n] `Y`
Migration table created successfully.
Next Batch Number is: 1. We recommend using Batch Number 0 so that it becomes the “first” migration [Default: 0]
Setting up Tables and Index Migrations
Created: … create_wp_commentmeta_table.php
Created: … create_wp_comments_table.php
Created: … create_wp_links_table.php
Created: … create_wp_options_table.php
Created: … create_wp_postmeta_table.php
Created: … create_wp_posts_table.php
Created: … create_wp_term_relationships_table.php
Created: … create_wp_term_taxonomy_table.php
Created: … create_wp_terms_table.php
Created: … create_wp_usermeta_table.php
Created: … create_wp_users_table.php

Setting up Foreign Key Migrations

Finished!

Boom! Just like that, we have all our migrations finished. It’s a bit of a nonsensical example, but just think of the use cases it has. The first one that comes to mind is, say you have an app built on another framework. There is an existing database for which you would like to quickly create migrations for, so that you can then move over to writing the Laravel code. With this tool, you can do just that. Just for reference, here is the output of the migration source code that was generated for us in this example.

create_wp_commentmeta_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpCommentmetaTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_commentmeta', function(Blueprint $table)
		{
			$table->bigInteger('meta_id', true)->unsigned();
			$table->bigInteger('comment_id')->unsigned()->default(0)->index('comment_id');
			$table->string('meta_key')->nullable()->index('meta_key');
			$table->text('meta_value')->nullable();
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_commentmeta');
	}

}

create_wp_comments_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpCommentsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_comments', function(Blueprint $table)
		{
			$table->bigInteger('comment_ID', true)->unsigned();
			$table->bigInteger('comment_post_ID')->unsigned()->default(0)->index('comment_post_ID');
			$table->text('comment_author');
			$table->string('comment_author_email', 100)->default('')->index('comment_author_email');
			$table->string('comment_author_url', 200)->default('');
			$table->string('comment_author_IP', 100)->default('');
			$table->dateTime('comment_date')->default('0000-00-00 00:00:00');
			$table->dateTime('comment_date_gmt')->default('0000-00-00 00:00:00')->index('comment_date_gmt');
			$table->text('comment_content', 65535);
			$table->integer('comment_karma')->default(0);
			$table->string('comment_approved', 20)->default('1');
			$table->string('comment_agent')->default('');
			$table->string('comment_type', 20)->default('');
			$table->bigInteger('comment_parent')->unsigned()->default(0)->index('comment_parent');
			$table->bigInteger('user_id')->unsigned()->default(0);
			$table->index(['comment_approved','comment_date_gmt'], 'comment_approved_date_gmt');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_comments');
	}

}

create_wp_links_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpLinksTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_links', function(Blueprint $table)
		{
			$table->bigInteger('link_id', true)->unsigned();
			$table->string('link_url')->default('');
			$table->string('link_name')->default('');
			$table->string('link_image')->default('');
			$table->string('link_target', 25)->default('');
			$table->string('link_description')->default('');
			$table->string('link_visible', 20)->default('Y')->index('link_visible');
			$table->bigInteger('link_owner')->unsigned()->default(1);
			$table->integer('link_rating')->default(0);
			$table->dateTime('link_updated')->default('0000-00-00 00:00:00');
			$table->string('link_rel')->default('');
			$table->text('link_notes', 16777215);
			$table->string('link_rss')->default('');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_links');
	}

}

create_wp_options_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpOptionsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_options', function(Blueprint $table)
		{
			$table->bigInteger('option_id', true)->unsigned();
			$table->string('option_name', 64)->default('')->unique('option_name');
			$table->text('option_value');
			$table->string('autoload', 20)->default('yes');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_options');
	}

}

create_wp_postmeta_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpPostmetaTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_postmeta', function(Blueprint $table)
		{
			$table->bigInteger('meta_id', true)->unsigned();
			$table->bigInteger('post_id')->unsigned()->default(0)->index('post_id');
			$table->string('meta_key')->nullable()->index('meta_key');
			$table->text('meta_value')->nullable();
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_postmeta');
	}

}

create_wp_posts_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpPostsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_posts', function(Blueprint $table)
		{
			$table->bigInteger('ID', true)->unsigned();
			$table->bigInteger('post_author')->unsigned()->default(0)->index('post_author');
			$table->dateTime('post_date')->default('0000-00-00 00:00:00');
			$table->dateTime('post_date_gmt')->default('0000-00-00 00:00:00');
			$table->text('post_content');
			$table->text('post_title', 65535);
			$table->text('post_excerpt', 65535);
			$table->string('post_status', 20)->default('publish');
			$table->string('comment_status', 20)->default('open');
			$table->string('ping_status', 20)->default('open');
			$table->string('post_password', 20)->default('');
			$table->string('post_name', 200)->default('')->index('post_name');
			$table->text('to_ping', 65535);
			$table->text('pinged', 65535);
			$table->dateTime('post_modified')->default('0000-00-00 00:00:00');
			$table->dateTime('post_modified_gmt')->default('0000-00-00 00:00:00');
			$table->text('post_content_filtered');
			$table->bigInteger('post_parent')->unsigned()->default(0)->index('post_parent');
			$table->string('guid')->default('');
			$table->integer('menu_order')->default(0);
			$table->string('post_type', 20)->default('post');
			$table->string('post_mime_type', 100)->default('');
			$table->bigInteger('comment_count')->default(0);
			$table->index(['post_type','post_status','post_date','ID'], 'type_status_date');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_posts');
	}

}

create_wp_term_relationships_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpTermRelationshipsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_term_relationships', function(Blueprint $table)
		{
			$table->bigInteger('object_id')->unsigned()->default(0);
			$table->bigInteger('term_taxonomy_id')->unsigned()->default(0)->index('term_taxonomy_id');
			$table->integer('term_order')->default(0);
			$table->primary(['object_id','term_taxonomy_id']);
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_term_relationships');
	}

}

create_wp_term_taxonomy_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpTermTaxonomyTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_term_taxonomy', function(Blueprint $table)
		{
			$table->bigInteger('term_taxonomy_id', true)->unsigned();
			$table->bigInteger('term_id')->unsigned()->default(0);
			$table->string('taxonomy', 32)->default('')->index('taxonomy');
			$table->text('description');
			$table->bigInteger('parent')->unsigned()->default(0);
			$table->bigInteger('count')->default(0);
			$table->unique(['term_id','taxonomy'], 'term_id_taxonomy');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_term_taxonomy');
	}

}

create_wp_terms_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpTermsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_terms', function(Blueprint $table)
		{
			$table->bigInteger('term_id', true)->unsigned();
			$table->string('name', 200)->default('')->index('name');
			$table->string('slug', 200)->default('')->index('slug');
			$table->bigInteger('term_group')->default(0);
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_terms');
	}

}

create_wp_usermeta_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpUsermetaTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_usermeta', function(Blueprint $table)
		{
			$table->bigInteger('umeta_id', true)->unsigned();
			$table->bigInteger('user_id')->unsigned()->default(0)->index('user_id');
			$table->string('meta_key')->nullable()->index('meta_key');
			$table->text('meta_value')->nullable();
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_usermeta');
	}

}

create_wp_users_table.php source

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateWpUsersTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('wp_users', function(Blueprint $table)
		{
			$table->bigInteger('ID', true)->unsigned();
			$table->string('user_login', 60)->default('')->index('user_login_key');
			$table->string('user_pass', 64)->default('');
			$table->string('user_nicename', 50)->default('')->index('user_nicename');
			$table->string('user_email', 100)->default('');
			$table->string('user_url', 100)->default('');
			$table->dateTime('user_registered')->default('0000-00-00 00:00:00');
			$table->string('user_activation_key', 60)->default('');
			$table->integer('user_status')->default(0);
			$table->string('display_name', 250)->default('');
		});
	}


	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('wp_users');
	}

}

Laravel Migration Generator Conclusion

As we can see, this is a really cool Laravel Migration Generator the community created. It’s a great way to reverse engineer existing databases as well as to help learn about how to create migrations. The files above give us a good overview of the various methods we can use off of the $table instance in our migrations files.

Leave a Reply