一般错误:1215无法添加外键约束,Laravel 5和MySQL

时间:2019-04-18 11:33:22

标签: php mysql laravel migration

在一个空白的Laravel项目中,我想在用户问题之间创建外键约束,其中users表将包含内置的Laravel {{ 1}},但User将是自定义模型。

运行Question后,会发生以下错误:

php artisan migrate

这是laravel生成的create_users_table迁移:

   Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `questions` add constraint `questions_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
  at /home/artur/Exposit/EDU/PHP/lara/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| 

这是我的迁移地点

 Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

我尝试将问题表的创建和外键约束的更改分为两个迁移,但是出现了相同的错误。 请注意,没有关于stackoverflow的相关答案对我有帮助。

6 个答案:

答案 0 :(得分:2)

Laravel 5.8添加了bigIncrements作为默认值

因此,外键字段类型不匹配。您会在“用户”表中看到bigIncrements(id),在问题表中看到未签名的整数(user_id)。

如何修复

  • 将原始迁移从bigIncrements()更改为just
    增量()
  • 或者在外键列中执行unsignedBigInteger()而不是 unsignedInteger()。

答案 1 :(得分:0)

主键和外键的数据类型必须相同。

请将questions迁移更新为:

Schema::create('questions', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('title');
    $table->string('slug')->unique();
    $table->text('body');
    $table->unsignedInteger('views')->default(0);
    $table->unsignedInteger('answers')->default(0);
    $table->integer('votes')->default(0);
    $table->unsignedInteger('best_answer_id')->nullable();
    $table->bigInteger('user_id')->unsigned()->nullable();
    $table->timestamps();
});

Schema::table('questions', function (Blueprint $table) {
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

如果best_answer_id也将成为外键,请同样进行。

答案 2 :(得分:0)

在用户表bigIncrements('id')中创建未签名的主键。

,它的类型是大整数

设置外键时,其外键也应未签名。

添加unsigned()函数并将类型从unsignedInteger更改为bigInteger

示例:

 Schema::create('questions', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->unsignedInteger('views')->default(0);
            $table->unsignedInteger('answers')->default(0);
            $table->integer('votes')->default(0);
            $table->unsignedInteger('best_answer_id')->nullable();
            $table->bigInteger('user_id')->unsigned();
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });

答案 3 :(得分:0)

最后在Schema :: create()函数中添加外键约束,像这样:

Schema::create('questions', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('title');
        $table->string('slug')->unique();
        $table->text('body');
        $table->unsignedInteger('views')->default(0);
        $table->unsignedInteger('answers')->default(0);
        $table->integer('votes')->default(0);
        $table->unsignedInteger('best_answer_id')->nullable();
        $table->unsignedInteger('user_id');
        $table->timestamps();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });

答案 4 :(得分:0)

更改迁移源表

Schema::create('table_name', function (Blueprint $table) {
$table->BigIncrements('id');

Schema::create('table_name', function (Blueprint $table) {
$table->increments('id');

答案 5 :(得分:0)

我如何为 Laravel 8 修复它: L8 中生成的所有迁移都只使用 $table->id();,即 bigInteger。确保在将包含外键的第二个表上,您有 $table->unsignedBigInteger('post_id');

首先设置正确的类型:

posts table

Schema::create('posts', function (Blueprint $table) {
 $table->id(); //note by default in laravel 8 this is bigint
 $table->string('title')->nullable();
 $table->timestamps();
});

comments table

Schema::create('comments', function (Blueprint $table) {
 $table->id();
 $table->string('description')->nullable();
 //foriegn key set up below
 $table->unsignedBigInteger('post_id');
 $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');

});

第二次对迁移文件重新排序(应该先运行posts迁移,然后才能运行comments文件,因为laravel找不到post的id来创建外键)

2021_04_10_043454_create_posts_table -> 04/10(较早的日期将首先运行) 2021_04_14_050712_create_posts_table -> 04/14(稍后日期)

最后, 先清除缓存 php artisan cache:clear 然后运行 ​​php artisan migrate