Migrations
A migration is a file that describes a database change in code: create a table, add a column. Migrations are stored in the project together with the code, so every developer and the server bring the database to the same shape with one command.
Where they live
Migration files are in the config/Migrations folder. They are handled by the Migrations plugin, which is already installed in a new project.
Creating
bin/cake bake migration CreateArticles title:string body:text published:boolean created modifiedThe migration name is followed by columns in the name:type form. From the word Create at the start of the name the generator understands that a new articles table is needed. A file with a date in its name appears in the folder; the date sets the order of execution.
The migration file
// config/Migrations/20260302101500_CreateArticles.php
use Migrations\AbstractMigration;
class CreateArticles extends AbstractMigration
{
public function change(): void
{
$table = $this->table('articles');
$table->addColumn('title', 'string', ['limit' => 255, 'null' => false])
->addColumn('body', 'text', ['null' => false])
->addColumn('published', 'boolean', ['default' => false, 'null' => false])
->addColumn('created', 'datetime', ['null' => false])
->addColumn('modified', 'datetime', ['null' => false])
->create();
}
}The id column with the primary key is added automatically. The change() method describes only the change; the plugin works out how to undo it. In recent plugin versions the parent class is called BaseMigration and has the same methods.
Running
bin/cake migrations migrateThe command runs the migrations that have not been run yet and prints their names. The articles table appears in the blog database.
Status and rollback
| Command | What it does |
|---|---|
bin/cake migrations status | Shows which migrations have run |
bin/cake migrations migrate | Runs the new ones |
bin/cake migrations rollback | Undoes the last one |
Column types
| Type | Purpose |
|---|---|
string | A string, limit is the length |
text | Long text |
integer | An integer |
decimal | An exact fractional number: precision, scale |
boolean | Yes or no |
datetime, date | Date with time, date |
Changing a table
To add a column, create a new migration:
bin/cake bake migration AddViewsToArticles views:integerpublic function change(): void
{
$this->table('articles')
->addColumn('views', 'integer', ['default' => 0, 'null' => false])
->update();
}For an existing table the chain ends with update(), for a new one with create(). After bin/cake migrations migrate articles get the views column.
When the ORM does not see a column
CakePHP remembers the table structure in a cache. When a new column exists in the database but the application does not notice it, clear this cache:
bin/cake schema_cache clearCommon mistake
A migration that has already run must not be edited: on other computers and on the server it is already applied and will not run again, so their databases stay as they were. Every new change is a new migration file.