Migrations

Migrations are a method of coding your database schema for both table creation and change control tracking. They allow you build out your tables in code, and track updates to those tables, then use that code to create and update the database tables.

Create A Migration

CakePHP allows for simple creation of migrations using the command line interface.

$ bin/cake bake migration CreatePhoneNumbers

This will create a migration file for the phone_numbers table within the application's /config/Migrations directory that is named with a date-time prefix then the user input. e.g. 20230627093822_CreatePhoneNumbers.php It is recommended to use the convention in the example above: the action and the table name. Tables hold multiple records, so the convention is table names are plural.

Update Your Migration

The Phinx package behind the migrations uses reversible migrations. This means you only need to define the "up" logic in your change() method, and Phinx figures out the "down" logic to rollback your migrations automatically.

By default your migration creates a field id for the primary key of the table. If you don't want to use that, you can set the id to false and define your own primary key. Also note that the primary key is an array and can be multiple fields.

  $table = $this->table('users', ['id' => false, 'primary_key' => ['email']]);
  $table->addPrimaryKey('email');

We're going to keep the default key and continue adding more fields. Open your newly created migration file.

<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class CreatePhoneNumbers extends AbstractMigration
{
  /**
   * Change Method.
   *
   * @return void
   */
  public function change(): void
  {
    $table = $this->table('phone_numbers');
    $table->addColumn('user_id', 'integer', ['null' => false])
      ->addColumn('phone_number', 'string', ['limit' => 15, 'null' => false])
      // null is only necessary if false, true is default
      ->addTimestamps(); // Adds the modified and created fields
    $table->create();
  }
}

Import Your Migrations

Now that your migration is ready to create your table you can run it.

$ bin\cake migrations migrate

Now you can check the status of your migrations.

$ bin\cake migrations status

If there is a problem, or you were just testing things, you can rollback your changes.

$ bin\cake migrations rollback

Update Your Table With Migrations

If you want to make changes to a table, you can create a migration for that too. Migration names cannot be duplicated, despite the prefixed timestamp. So you can only have one UpdateUsers migration, so it is better to be specific in your migration name. For example, AddPhoneTypeToPhoneNumbers. First create your migration:

$ bin\cake bake migration AddPhoneTypeToPhoneNumbers

Then update your new migration with your changes.

public function change(): void
{
  $table = $this->table('phone_numbers');
  $table->addColumn('type', 'string', ['limit' => 1, 'null' => false]);
  $table->update();
}

Then run your migration.

$ bin\cake migrations migrate

Create a Migration from an Existing Table

In addition to creating migrations manual, you can create one from an existing table in your database. First, rollback our current changes so we only snapshot the Users table we created. You'll have to run rollback multiple times to undo each migration. Check your migration status to ensure all migrations are "down" then run migration_snapshot to grab our initial database tables. Since we only have a Users table, we can name this "CreateUsers" (the phinxlog table is ignored) otherwise the name should identify the fact that isn't just a single table.

$ bin\cake bake migration_snapshot CreateUsers

Now if you perform a migration status you'll see the new migration is included and has a status of "up" and if you run a rollback, it will remove the Users table, including any records you may have in it.

Create Your Models

Now that you've created your phone-numbers table, create the Entity and Table models just as you did with your Users table in Database and Model.