Reader Stacks

How to Change a Column's Data Type in a Laravel Migration

Changing a column type after it is already in production requires the doctrine/dbal package (or Laravel 11's native alternative) and a real rollback plan.

How to Change a Column's Data Type in a Laravel Migration

Changing a column's type — say, a string that needs to become a text, or an integer that needs to become unsignedBigInteger — uses the same change() method as adding a column, but with a real dependency requirement that trips people up.

The migration

Schema::table('products', function (Blueprint $table) {
    $table->text('description')->change();
});

Run it the normal way:

php artisan migrate

The dependency you probably need

On Laravel 10 and earlier, calling ->change() requires doctrine/dbal:

composer require doctrine/dbal

Without it, the migration fails immediately with a clear "class not found" error rather than silently doing nothing — so if you hit this, it's not a sign anything is wrong with the migration itself, just a missing package.

Laravel 11+: doctrine/dbal is no longer required

Laravel 11 replaced the Doctrine-based schema introspection with its own, so a fresh Laravel 11 or 12 project does not need doctrine/dbal for ->change() to work. If you're upgrading an older project that already has it installed, it's safe to remove once you've confirmed nothing else in the app depends on it directly.

Changing a column safely on a table with real data

Two things matter more than the syntax:

  • Data compatibility — narrowing a type (e.g. text down to string(255)) can silently truncate existing rows. Check the actual data range before narrowing anything.
  • A working down() — write the reverse change explicitly rather than leaving it empty, so a bad deploy can actually be rolled back:
public function down(): void
{
    Schema::table('products', function (Blueprint $table) {
        $table->string('description', 255)->change();
    });
}

On a large production table, also consider whether the change requires a full table rewrite at the database level (most type changes on MySQL/InnoDB do) and plan the deploy window accordingly — this is a database-engine concern, not something the migration file itself controls.

Topics: Database Migrations