SQLite Note
If you are using SQLite, the doctrine/dbal package is required to modify columns. Run composer require doctrine/dbal to install it.
Migrations are like version control for your database. They allow you to define and share your database schema using PHP classes instead of raw SQL files. Migrations work with both MySQL and SQLite.
Use the CLI to generate a migration file:
$ php cli make:migration create_users_table
This creates a file in database/migrations/ with a timestamp prefix, e.g. 2024_01_01_120000_create_users_table.php.
The migration file contains an anonymous class extending Migration:
use Simple\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
$this->schema()->create('users', function ($table) {
$table->id();
$table->timestamps();
});
}
public function down(): void
{
$this->schema()->dropIfExists('users');
}
};
Each migration must implement two methods:
$this->schema() to access the Schema Builder.The Schema Builder provides a fluent API for creating and modifying tables:
public function up(): void
{
$this->schema()->create('posts', function ($table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title');
$table->text('body');
$table->timestamps();
$table->softDeletes();
});
}
Apply all pending migrations:
$ php cli migrate
This runs any migration files in database/migrations/ that have not yet been applied. A migrations table tracks which migrations have been run.
View the status of all migration files (which have run and which are pending):
$ php cli migrate:status
Output:
Migration Status Batch
2024_01_01_000001_create_users_table.php Ran 1
2024_01_01_000002_create_posts_table.php Pending
Drop all tables and re-run every migration from scratch:
$ php cli migrate:fresh
This is useful during development when you want to rebuild your entire database schema. All user tables are dropped and all migrations are re-applied in order.
The schema builder blueprint offers a variety of methods that correspond to the different types of columns you can add to your database tables. Call these inside the closure passed to $this->schema()->create() or $this->schema()->table().
Creates an auto-incrementing UNSIGNED BIGINT (primary key) equivalent column.
$table->bigIncrements('id');
Creates a BIGINT equivalent column.
$table->bigInteger('votes');
Creates a BLOB equivalent column.
$table->binary('photo');
Creates a BOOLEAN equivalent column.
$table->boolean('confirmed');
Creates a CHAR equivalent column with a given length.
$table->char('name', 100);
Creates a DATETIME (with timezone) equivalent column with optional precision.
$table->dateTimeTz('created_at', $precision = 0);
Creates a DATETIME equivalent column with optional precision.
$table->dateTime('created_at', $precision = 0);
Creates a DATE equivalent column.
$table->date('created_at');
Creates a DECIMAL equivalent column with given precision (total digits) and scale (decimal digits).
$table->decimal('amount', $precision = 8, $scale = 2);
Creates a DOUBLE equivalent column with given precision and scale.
$table->double('amount', 8, 2);
Creates an ENUM equivalent column with valid values.
$table->enum('difficulty', ['easy', 'hard']);
Creates a FLOAT equivalent column with given precision and scale.
$table->float('amount', 8, 2);
Creates an UNSIGNED BIGINT equivalent column (typically used for foreign keys).
$table->foreignId('user_id');
Adds a {column}_id equivalent column for a given model class.
$table->foreignIdFor(User::class);
Creates a ULID equivalent column.
$table->foreignUlid('user_id');
Creates a UUID equivalent column.
$table->foreignUuid('user_id');
Creates a GEOMETRY equivalent column.
$table->geometry('positions');
Creates a GEOMETRYCOLLECTION equivalent column.
$table->geometryCollection('positions');
Alias of bigIncrements. Creates an auto-incrementing UNSIGNED BIGINT primary key column. Default column name is id.
$table->id();
Creates an auto-incrementing UNSIGNED INTEGER equivalent column as a primary key.
$table->increments('id');
Creates an INTEGER equivalent column.
$table->integer('votes');
Creates a VARCHAR equivalent column (uses INET on PostgreSQL).
$table->ipAddress('visitor');
Creates a JSON equivalent column.
$table->json('options');
Creates a JSONB equivalent column.
$table->jsonb('options');
Creates a LINESTRING equivalent column.
$table->lineString('positions');
Creates a LONGTEXT equivalent column.
$table->longText('description');
Creates a column intended to hold a MAC address.
$table->macAddress('device');
Creates an auto-incrementing UNSIGNED MEDIUMINT equivalent column as a primary key.
$table->mediumIncrements('id');
Creates a MEDIUMINT equivalent column.
$table->mediumInteger('votes');
Creates a MEDIUMTEXT equivalent column.
$table->mediumText('description');
Convenience method that adds a {column}_id (UNSIGNED BIGINT) and {column}_type (VARCHAR) column for polymorphic relationships.
$table->morphs('taggable');
Creates a MULTILINESTRING equivalent column.
$table->multiLineString('positions');
Creates a MULTIPOINT equivalent column.
$table->multiPoint('positions');
Creates a MULTIPOLYGON equivalent column.
$table->multiPolygon('positions');
Alias of timestamps method.
$table->nullableTimestamps(0);
Similar to morphs but the columns are created as nullable.
$table->nullableMorphs('taggable');
Similar to ulidMorphs but the columns are created as nullable.
$table->nullableUlidMorphs('taggable');
Similar to uuidMorphs but the columns are created as nullable.
$table->nullableUuidMorphs('taggable');
Creates a POINT equivalent column.
$table->point('position');
Creates a POLYGON equivalent column.
$table->polygon('position');
Creates a nullable VARCHAR(100) column to store the "remember me" authentication token.
$table->rememberToken();
Creates a SET equivalent column with a given list of valid values.
$table->set('flavors', ['strawberry', 'vanilla']);
Creates an auto-incrementing UNSIGNED SMALLINT equivalent column as a primary key.
$table->smallIncrements('id');
Creates a SMALLINT equivalent column.
$table->smallInteger('votes');
Adds a nullable deleted_at TIMESTAMP (with timezone) column for soft deletes.
$table->softDeletesTz($column = 'deleted_at', $precision = 0);
Adds a nullable deleted_at TIMESTAMP column for soft deletes.
$table->softDeletes($column = 'deleted_at', $precision = 0);
Creates a VARCHAR equivalent column of the given length.
$table->string('name', 100);
Creates a TEXT equivalent column.
$table->text('description');
Creates a TIME (with timezone) equivalent column with optional precision.
$table->timeTz('sunrise', $precision = 0);
Creates a TIME equivalent column with optional precision.
$table->time('sunrise', $precision = 0);
Creates a TIMESTAMP (with timezone) equivalent column with optional precision.
$table->timestampTz('added_at', $precision = 0);
Creates a TIMESTAMP equivalent column with optional precision.
$table->timestamp('added_at', $precision = 0);
Creates created_at and updated_at TIMESTAMP (with timezone) columns.
$table->timestampsTz($precision = 0);
Creates created_at and updated_at TIMESTAMP columns.
$table->timestamps($precision = 0);
Creates an auto-incrementing UNSIGNED TINYINT equivalent column as a primary key.
$table->tinyIncrements('id');
Creates a TINYINT equivalent column.
$table->tinyInteger('votes');
Creates a TINYTEXT equivalent column.
$table->tinyText('notes');
Creates an UNSIGNED BIGINT equivalent column.
$table->unsignedBigInteger('votes');
Creates an UNSIGNED DECIMAL equivalent column with optional precision and scale.
$table->unsignedDecimal('amount', $precision = 8, $scale = 2);
Creates an UNSIGNED INTEGER equivalent column.
$table->unsignedInteger('votes');
Creates an UNSIGNED MEDIUMINT equivalent column.
$table->unsignedMediumInteger('votes');
Creates an UNSIGNED SMALLINT equivalent column.
$table->unsignedSmallInteger('votes');
Creates an UNSIGNED TINYINT equivalent column.
$table->unsignedTinyInteger('votes');
Convenience method that adds a {column}_id CHAR(26) and {column}_type VARCHAR column for polymorphic relationships using ULID identifiers.
$table->ulidMorphs('taggable');
Convenience method that adds a {column}_id CHAR(36) and {column}_type VARCHAR column for polymorphic relationships using UUID identifiers.
$table->uuidMorphs('taggable');
Creates a ULID equivalent column.
$table->ulid('id');
Creates a UUID equivalent column.
$table->uuid('id');
Creates a YEAR equivalent column.
$table->year('birth_year');
In addition to the column types listed above, you may chain column "modifiers" when adding a column:
$table->string('email')->nullable()->default('none');
| Modifier | Description |
|---|---|
->after('column') |
Place the column "after" another column (MySQL). |
->autoIncrement() |
Set INTEGER columns as auto-incrementing (primary key). |
->charset('utf8mb4') |
Specify a character set for the column (MySQL). |
->collation('utf8mb4_unicode_ci') |
Specify a collation for the column (MySQL/PostgreSQL/SQL Server). |
->comment('my comment') |
Add a comment to a column (MySQL/PostgreSQL). |
->default($value) |
Specify a "default" value for the column. |
->first() |
Place the column "first" in the table (MySQL). |
->from($integer) |
Set the starting value of an auto-incrementing field (MySQL/PostgreSQL). |
->invisible() |
Make the column "invisible" to SELECT * queries (MySQL). |
->nullable($value = true) |
Allow NULL values to be inserted into the column. |
->storedAs($expression) |
Create a stored generated column (MySQL/PostgreSQL). |
->unsigned() |
Set INTEGER columns as UNSIGNED (MySQL). |
->useCurrent() |
Set TIMESTAMP columns to use CURRENT_TIMESTAMP as default value. |
->useCurrentOnUpdate() |
Set TIMESTAMP columns to use CURRENT_TIMESTAMP on update (MySQL). |
->virtualAs($expression) |
Create a virtual generated column (MySQL/PostgreSQL/SQLite). |
->generatedAs($expression) |
Create an identity column with sequence options (PostgreSQL). |
->always() |
Defines precedence of sequence values over input for an identity column (PostgreSQL). |
->isGeometry() |
Set spatial column type to geometry (PostgreSQL). |
The change method allows you to modify the type and attributes of existing columns. For example, to increase the size of a string column:
$this->schema()->table('users', function ($table) {
$table->string('name', 50)->change();
});
When modifying a column, you must explicitly include all modifiers you want to retain:
$this->schema()->table('users', function ($table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});
If you are using SQLite, the doctrine/dbal package is required to modify columns. Run composer require doctrine/dbal to install it.
To rename a column, use the renameColumn method:
$this->schema()->table('users', function ($table) {
$table->renameColumn('from', 'to');
});
To drop a column, use the dropColumn method:
$this->schema()->table('users', function ($table) {
$table->dropColumn('votes');
});
You may drop multiple columns at once:
$this->schema()->table('users', function ($table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
Convenience methods for dropping common column types:
| Method | Description |
|---|---|
$table->dropMorphs('morphable') |
Drop the morphable_id and morphable_type columns. |
$table->dropRememberToken() |
Drop the remember_token column. |
$table->dropSoftDeletes() |
Drop the deleted_at column. |
$table->dropTimestamps() |
Drop the created_at and updated_at columns. |