Everything you need to know about CakePHP Migrations

Migrations is a powerful feature in CakePHP. It gives you a tool to create or import database structure and data through command line interface. CakePHP Migrations is installed by default when you install CakePHP.

Database migrations creates , updates or deletes MySQL tables using through PHP code which can be run via CLI or through scripts. You can manage database updates in versions which help to track changes and make it easier to run database updates in the system.

It is also useful in plugins where a plugin has MSQL tables which are initially required to be created and to be deleted when uninstalling the plugin. All in all migrations automates the database related operations in an easier and convenient way through developer friendly code and conventions.

1. Using Phinx

Phinx is a standalone command line tool for managing database Migrations. The official Migrations plugin for CakePHP is based on this tool.

If you have got a phinx.yml file at the root of your CakePHP installation if is already installed. If it is not there you can install it. Type:

php composer.phar require robmorgan/phinx

And then

vendor/bin/phinx init

to initiate the phinx which will create a phinx.yml configuration file in the root of your app.

Also, you need to create folders in your project following the structure db/migrations with adequate writable permissions. It is where your migration files will live. You can change this location in phinx.yml file.

Creating CakePHP Migrations

Create your first migration. I name it CreateUsersTable.

vendor/bin/phinx create CreateUsersTable

It will generate a php file named something like 20191119100625_create_users_table.php with following code:

<?php

use Phinx\Migration\AbstractMigration;

class CreateUsersTable extends AbstractMigration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* addCustomColumn
* renameColumn
* addIndex
* addForeignKey
*
* Any other destructive changes will result in an error when trying to
* rollback the migration.
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{

}
}

Note: Generated file format is YYYYMMDDHHMMSS_your_migration_name.php after camel-case YourMigrationName is converted into lowercase characters separate by underscore(_).

Now,  since the create operation has created a skeleton file lets place some table creation logic inside the change function so that it looks like:

public function change()
{
$table = $this->table('users');
$table->addColumn('full_name', 'string',
[ 'default' => null,
'limit' => 100,
'null' => false,
])
->addColumn('created', 'datetime')
->addColumn('modified', 'datetime');
$table->create();
}

Running Migrations

Once we have updated the change method in migration file lets run it to create the table.

In the console, type:

vendor/bin/phinx migrate

It should create two new tables, users and phinx where later is used to record log of all migration operations run within the system.

In case you are doing this for a plugin, you may need to set the –path parameter so the migration files are generated at correct location. For example

vendor/bin/phinx create --path plugins/myplugin/config/Migrations CreateUsersTable

Here, since we are creating a migration in a different location than the default db/migrations location we have to tell phinx to include it while looking up for a migration to be run.

To do this edit the phinx.yml file to include this location. So the paths configuration, from

paths:
    migrations: '%%PHINX_CONFIG_DIR%%/db/migrations'

Becomes:

paths:
    migrations:
        - '%%PHINX_CONFIG_DIR%%/db/migrations'
        - '%%PHINX_CONFIG_DIR%%/plugins/myplugin/config/Migrations'

Running vendor/bin/phinx migrate next time would scan the new directory for available migrations to be run.

2. Using CakePHP Migrations plugin

Although Migrations plugin uses phinx in the background it can also be run using bin/cake CLI too. The examples below demonstrate the operations via bin/cake if the phinx is not available.

To check whether migrations is installed in your CakePHP application, type:

bin/cake migrations --version

It should print something like:

Migrations plugin, based on Phinx by Rob Morgan. 0.11.1

If it is not installed type to install it

composer require cakephp/migrations

After installation there should be an entry in the composer.json, as following

"require": {
    "cakephp/migrations": "dev-master"
}

If you just installed it type composer dumpautoload to regenerate file auto-load script files.

Once migration are installed and working do the following to generate your first migration script.

bin/cake migrations create CreateUsersTable

It will create a 20191119090031_CreateUsersTable.php file with the following contents:

<?php
use Migrations\AbstractMigration;

class CreateUsersTable extends AbstractMigration
{
    /**
    * Change Method.
    *
    * More information on this method is available here:
    * http://docs.phinx.org/en/latest/migrations.html#the-change-method
    * @return void
    */
    public function change()
    {
    }
}

Note: Generated file format is YYYYMMDDHHMMSS_CreateUsersTable.php

Since the create operation above created a skelelton file let place some table creation logic inside the change function so that it looks like

<?php
use Migrations\AbstractMigration;

class CreateUsersTable extends AbstractMigration
{
    /**
    * Change Method.
    *
    * More information on this method is available here:
    * http://docs.phinx.org/en/latest/migrations.html#the-change-method
    * @return void
    */
    public function change()
    {
        $table = $this->table('users');
        $table->addColumn('full_name', 'string', [
            'default' => null,
            'limit' => 100,
            'null' => false,
        ])
        ->addColumn('created', 'datetime')
        ->addColumn('modified', 'datetime');
        $table->create();
    }
}

The code above creates a users table with a full_name field along with created and modified fields which are of type, string, datetime and datetime respecively.

Not lets run it to create a table.

bin/cake migrations migrate

After running it go and check your database. It should have a new users table*

Alternatively CakePHP comes with a Phinx wrapper using which you can run same migration commands with little bit different syntax. For example

vendor/bin/phinx create CreateUsersTable

It will generate a php file with following code:

<?php

use Phinx\Migration\AbstractMigration;

class CreateUsersTable extends AbstractMigration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* addCustomColumn
* renameColumn
* addIndex
* addForeignKey
*
* Any other destructive changes will result in an error when trying to
* rollback the migration.
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{

}
}

Cakephp 3 uses Phinx command line tool for database migrations which makes this process easier. It give additional configuration mechanism which uses [root]/phinx.yml file a configuration file to be used for migrations and seeds paths. Alter this file to change paths to your migrations and seeds folder.

Running Migrations

To run a migration created earlier using steps above do:

bin/cake migrations migrate

You can see the migrations history in phinxlog database table. Above is the brief explanation of how migrations work. Hope it will help you to get started with database migrations. For any queries related to this topic you can comment here J

* – Also notice that there is a phinxlog table as well, if you phinx wrapper enabled. In fact . This is very useful table and it tracks all the migration operations ran on the system as a log.

Leave a Reply