MySQL数据库的Laravel迁移“无法添加外键约束”错误

Posted

技术标签:

【中文标题】MySQL数据库的Laravel迁移“无法添加外键约束”错误【英文标题】:Laravel migration "Cannot add foreign key constraint" error with MySQL database 【发布时间】:2019-01-15 10:04:20 【问题描述】:

我正在开发一个 Laravel 应用程序。我正在使用 mysql 作为数据库。我创建了一个模型类,并试图在其上运行迁移。但是,当我运行迁移时,添加外键约束时出现错误。这是我到目前为止所做的。

首先我迁移了运行此命令的内置 Laravel 用户模型。

php artisan migrate

用户表已在数据库中创建。

然后我创建了另一个运行此命令的模型。

php artisan make:model TodoItem -m

然后我将以下代码添加到迁移文件中。

class CreateTodoItemsTable extends Migration

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('todo_items', function (Blueprint $table) 
            $table->text('about');
            $table->integer('user_id');
            $table->increments('id');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('todo_items');
    

正如您在上面看到的,我通过向 todo_items 表添加外键来建立 users 表和 todo_items 表之间的关系。然后,我尝试通过运行此命令来迁移 TodoItem 模型。

php artisan migrate

当我运行命令时,我得到了这个错误。

  Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `todo_items` add constraint `todo_items_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)

  at /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) 
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         
    668| 

 Exception trace:

  1   PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint")
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  Please use the argument -v to see more details.

我在之前使用 Postgresql 的项目中做了同样的事情。我工作得很好。对于这个项目,我使用的是 MySQL 数据库,现在它给了我上述错误。

【问题讨论】:

【参考方案1】:

这是因为您在迁移文件中添加了 $table->integer('user_id');。您必须添加unsignedInteger 而不是integer,因为users 表的原始id 列是unsigned(并且两列必须完全相同)。

[编辑]

从 Laravel 5.8 开始,默认 users 表的 id 列类型不再是 integer。现在是bigInteger

【讨论】:

【参考方案2】:

试试

    $table->unsignedBigInteger('user_id')->nullable()->index();  
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

【讨论】:

请始终在代码中添加一些解释,以改进您的答案并向未来用户提供更多信息【参考方案3】:

改变这个

$table->integer('user_id');

到这里

$table->unsignedInteger('user_id')->nullable(false);

【讨论】:

【参考方案4】:

尝试像这样运行它,这应该可以工作。

//还有,做我上面的人发布的未签名的事情

public function up()

    Schema::create('todo_items', function (Blueprint $table) 
        $table->text('about');
        $table->integer('user_id');
        $table->increments('id');
        $table->timestamps();

    );
    Schema::table('todo_items', function(Blueprint $table) 
        $table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');
    );

【讨论】:

【参考方案5】:

问题是mysql在创建表期间不需要外键,或者laravel以错误的顺序发出它们。

简而言之,这不起作用:

Schema::create('todo_items', function (Blueprint $table) 
    $table->text('about');
    $table->integer('user_id')->unsigned();
    $table->increments('id');
    $table->timestamps();

    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
);

这行得通:

  Schema::create('todo_items', function (Blueprint $table) 
    $table->text('about');
    $table->integer('user_id')->unsigned();
    $table->increments('id');
    $table->timestamps();

);

Schema::table('todo_items',  function(Blueprint $table)

    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
);

【讨论】:

以上是关于MySQL数据库的Laravel迁移“无法添加外键约束”错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 迁移:无法添加外键约束

Laravel 5.2 迁移:无法添加 char 数据类型的外键

迁移问题:无法在laravel中添加外键约束

MySQL 1215无法添加外键约束 - Laravel 5

Laravel 表迁移:无法添加外键约束

无法添加外键约束 - Laravel 迁移错误