Migrations
A migration is a class that describes one change of the database structure: create a table, add a column. Migrations are stored with the code, so the database of any developer and of the server is brought to the right shape with one command. The files live in the app/Database/Migrations folder.
Creating a migration
php spark make:migration CreatePostsA file with a date in its name appears in the folder, for example 2026-03-02-101500_CreatePosts.php. The date sets the order of execution. Describe the posts table in it:
// app/Database/Migrations/2026-03-02-101500_CreatePosts.php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreatePosts extends Migration
{
public function up()
{
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'title' => ['type' => 'VARCHAR', 'constraint' => 255],
'body' => ['type' => 'TEXT'],
'status' => ['type' => 'TINYINT', 'default' => 0],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->createTable('posts');
}
public function down()
{
$this->forge->dropTable('posts');
}
}The up() method makes the change, down() undoes it. The $this->forge object creates and alters tables. The second argument of addKey() — true — makes the key primary.
Describing a column
| Key | Meaning |
|---|---|
type | The type: INT, VARCHAR, TEXT, DECIMAL, DATETIME |
constraint | The length: 255 for a string, '10,2' for DECIMAL |
unsigned | Non-negative numbers only |
auto_increment | Automatic numbering |
null | May be empty |
default | The default value |
unique | Values do not repeat |
Running
php spark migrateCodeIgniter runs only the migrations that have not been run yet and remembers them in the service table migrations. After the command the posts table appears in the database. The state can be checked like this:
php spark migrate:statusThe command prints the list of migrations and marks which of them have been run.
Rolling back
php spark migrate:rollbackThe command calls down() of the last batch of migrations — the posts table disappears. php spark migrate:refresh undoes all migrations and runs them again.
Changing a table
To add a column to an existing table, create a new migration: php spark make:migration AddSlugToPosts.
public function up()
{
$this->forge->addColumn('posts', [
'slug' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true, 'after' => 'title'],
]);
}
public function down()
{
$this->forge->dropColumn('posts', 'slug');
}After php spark migrate the table has a slug column.
Common mistake
A migration that has already run must not be edited: CodeIgniter considers it applied and will not run it again, so your teammates' and the server's databases stay as they were. Create a new migration for every change. And do not run migrate:refresh or migrate:rollback on the live server — they drop tables together with the data.