Laravel分类迁移出现errno:150外键约束错误求助
The error you're hitting happens because the data type of your parent_id field doesn't match the type of the id field it references. Let's break this down and fix it step by step:
Why This Error Occurs
$table->bigIncrements('id')creates an unsigned big integer (unsigned BIGINT) for your primary key.- But your
parent_idis defined as$table->integer('parent_id')->unsigned()which makes it an unsigned integer (unsigned INT)—a smaller, incompatible data type. MySQL rejects foreign key constraints when column types don't match exactly.
Solution 1: Align Column Types in the Original Migration
Update your parent_id to use unsignedBigInteger so it matches the id column's type:
public function up() { Schema::create('categories', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('title'); $table->string('slug'); // Match the id column's type with unsignedBigInteger $table->unsignedBigInteger('parent_id')->default(0); $table->timestamps(); }); Schema::table('categories', function (Blueprint $table) { $table->foreign('parent_id') ->references('id') ->on('categories') ->onUpdate('cascade') ->onDelete('cascade'); }); }
Solution 2: Use Laravel's Shorthand (Laravel 8+)
If you're on Laravel 8 or newer, you can simplify this with the foreignId method—it automatically creates an unsignedBigInteger field and sets up the foreign key in one line:
public function up() { Schema::create('categories', function (Blueprint $table) { $table->id(); // Shorthand for bigIncrements('id') $table->string('title'); $table->string('slug'); // foreignId handles type and constraint in one step $table->foreignId('parent_id') ->default(0) ->constrained('categories') ->onUpdate('cascade') ->onDelete('cascade'); $table->timestamps(); }); }
If You've Already Run the Old Migration
If you already executed the original migration (and the table exists), don't edit the old migration file directly. Instead:
- Roll back the migration first:
php artisan migrate:rollback - Run the updated migration:
php artisan migrate
Alternatively, create a new migration to modify the parent_id column type:
// Example migration file: 2024_05_20_123456_fix_category_parent_id_type.php public function up() { Schema::table('categories', function (Blueprint $table) { // Drop existing foreign key if it was partially created try { $table->dropForeign('categories_parent_id_foreign'); } catch (\Exception $e) { // Ignore if the foreign key doesn't exist } // Change column type to match id $table->unsignedBigInteger('parent_id')->default(0)->change(); // Re-add the foreign key constraint $table->foreign('parent_id') ->references('id') ->on('categories') ->onUpdate('cascade') ->onDelete('cascade'); }); } public function down() { Schema::table('categories', function (Blueprint $table) { $table->dropForeign('categories_parent_id_foreign'); $table->integer('parent_id')->unsigned()->default(0)->change(); }); }
Run this new migration with:
php artisan migrate
内容的提问来源于stack exchange,提问作者Mostafa Norzade

