Postgres and Laravel how to change column from type string to integer?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Database Migrations: Changing Data Types from String to Integer in PostgreSQL with Laravel

As developers working with relational databases like PostgreSQL, managing schema changes through migrations is a daily task. One of the most common stumbling blocks developers encounter is altering column types, especially when moving from flexible string types (like VARCHAR or TEXT) to strict numeric types (like INTEGER).

This post dives deep into a specific scenario: how to correctly change a column type in PostgreSQL using Laravel migrations, addressing the exact error you encountered when trying to auto-cast. We will move beyond the failed attempt and implement the precise SQL syntax required for seamless data migration.

The Pitfall of Automatic Casting in Database Migrations

You correctly identified the issue. When attempting to execute a simple ALTER TABLE ... TYPE command within a Laravel migration, the framework often relies on automatic type casting provided by the underlying database driver (PDO). However, PostgreSQL is strict about this operation.

As demonstrated by your error:

ERROR:  column "company_id" cannot be cast automatically to type integer
HINT:  You might need to specify "USING company_id::integer".

This error tells us that while Laravel's Schema builder is convenient, for complex or non-standard type changes on PostgreSQL, we must explicitly provide the conversion method. Simply calling $table->integer('company_id')->change() delegates the casting responsibility to the database, which fails without explicit instruction.

The Solution: Using DB::raw() for Explicit Casting

To resolve this, we need to bypass the standard Schema builder syntax and execute the specific PostgreSQL command directly using Laravel's Query Builder via the DB::raw() method. This allows us to inject the necessary USING clause into the ALTER TABLE statement.

Here is how you implement the change correctly within your migration file:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class ChangeCompanyIdType extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        DB::unprepared("ALTER TABLE job_listings ALTER company_id TYPE INTEGER USING company_id::integer");
        // Alternatively, a slightly cleaner approach using DB::raw() if supported by the specific Laravel version/setup:
        // Schema::table('job_listings', function (Blueprint $table) {
        //     DB::raw('ALTER TABLE job_listings ALTER company_id TYPE INTEGER USING company_id::integer');
        // });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        // Logic to revert the change, if necessary.
    }
}

Deconstructing the Code

The most robust way to handle this type of operation is by using DB::raw(). This method allows you to execute arbitrary SQL directly against the database.

In the example above, we use:
DB::unprepared("ALTER TABLE job_listings ALTER company_id TYPE INTEGER USING company_id::integer");

  1. ALTER TABLE job_listings: Specifies which table we are modifying.
  2. ALTER company_id TYPE INTEGER: The core instruction to change the column type to integer.
  3. USING company_id::integer: This is the crucial part. It explicitly tells PostgreSQL how to perform the conversion—it casts the existing string values in the company_id column into the new INTEGER format.

This explicit instruction ensures that data integrity is maintained, as we are telling the database exactly how to handle the transformation, thus avoiding the automatic casting failure.

Best Practices for Database Schema Management

When managing complex schema changes in any framework, including Laravel, always assume the database engine requires explicit instructions for non-trivial alterations. This principle applies whether you are using MySQL, SQL Server, or PostgreSQL.

When developing robust applications with Laravel, understanding these low-level interactions is key. For general guidance on building powerful and clean code structures within the Laravel ecosystem, exploring resources from laravelcompany.com is highly recommended. Mastering migrations ensures that your application's database structure evolves predictably and reliably over time.

Conclusion

Changing a column type from string to integer in PostgreSQL via a Laravel migration requires moving beyond simple Schema builder calls and engaging directly with the underlying SQL commands. By utilizing DB::raw() and explicitly specifying the casting method using USING, you gain complete control over the data transformation process, ensuring your migrations execute successfully and maintain perfect data integrity. Always test these changes thoroughly in a development environment before deploying to production.