我试图在Laravel中创建外键,但是当我使用artisan迁移我的表时,我抛出了以下错误:

[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign 
key (`user_id`) references `users` (`id`))     

我的迁移代码如下:

优先级迁移文件

public function up()
{
    //
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id');
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
    Schema::drop('priorities');
}

用户迁移文件

public function up()
{
    //
    Schema::table('users', function($table)
    {
    $table->create();
    $table->increments('id');
    $table->string('email');
    $table->string('first_name');
    $table->string('password');
    $table->string('email_code');
    $table->string('time_created');
    $table->string('ip');
    $table->string('confirmed');
    $table->string('user_role');
    $table->string('salt');
    $table->string('last_login');

    $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
        Schemea::drop('users');
}

关于我做错了什么,我现在想要得到这个,因为我有很多表,我需要创建例如用户,客户端,项目,任务,状态,优先级,类型,团队。理想情况下,我想创建表持有这些数据与外键,即clients_project和project_tasks等。

希望有人能帮我开始。


当前回答

有时这种错误可能是由于迁移的顺序造成的。

Users和Order是两个表

订单表有用户的外键 (在迁移过程中,如果Order表先迁移,则会导致问题,因为没有用户匹配外键)

解决方案: 只需将您的Order Update表放在用户下面进行更新

例子: 在我的例子中,教育和大学表 教育表

public function up()
{
    Schema::create('doc_education', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('uni_id')->unsigned()->nullable();
        $table->timestamps();
    });
}

在大学里

    Schema::create('doc_universties', function (Blueprint $table) {
        $table->increments('id');
        $table->string('uni_name');
        $table->string('location')->nullable();
        $table->timestamps();

        //
    });



Schema::table('doc_education', function(Blueprint $table) {
        $table->foreign('uni_id')->references('id')
        ->on('doc_universties')->onDelete('cascade');
    });

其他回答

你可以直接在整型列中传递布尔参数,说它是否应该是无符号的。在laravel 5.4下面的代码解决了我的问题。

        $table->integer('user_id', false, true);

这里第二个参数false表示它不应该是自动递增的,第三个参数true表示它应该是无符号的。可以将外键约束保留在同一迁移中,也可以将其分离。两者都适用。

在我的案例中,问题在于迁移时机,在创建迁移时要小心,首先创建子迁移,而不是基础迁移。因为如果你先创建base migration,有外键就会寻找子表,不会有抛出异常的表。

进一步:

当您创建迁移时,它的开头有一个时间戳。假设你已经创建了一个迁移猫,它看起来像2015_08_19_075954_the_cats_time.php,它有这样的代码

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class TheCatsTime extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('cat', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');  
            $table->date('date_of_birth');
            $table->integer('breed_id')->unsigned()->nullable(); 
        });

        Schema::table('cat', function($table) {
        $table->foreign('breed_id')->references('id')->on('breed');
      });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('cat');
    }
}

在创建基表之后,创建另一个迁移品种,即子表,它有自己的创建时间和日期戳。 代码如下所示:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class BreedTime extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('breed', function (Blueprint $table) {
             $table->increments('id');    
             $table->string('name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('breed');
    }
}

看起来这两个表都是正确的,但当你运行PHP artisan迁移。它会抛出一个异常,因为迁移会首先在你的数据库中创建基表因为你先创建了这个迁移,我们的基表有外键约束,它会寻找子表,而子表不存在,这可能是一个异常。

So:

首先创建子表迁移。 在创建子迁移之后创建基表迁移。 PHP工匠迁移。

做就行了

另一个原因可能是DB引擎类型。Laravel默认使用MyISAM引擎。所以如果你需要强制外键引用检查,你应该使用InnoDB作为你的引擎。

这个设置在config/database.php文件中。将引擎改为'engine' => 'InnoDB'

另外,如果您试图对现有表执行此操作,请使用

DB::statement("ALTER TABLE ' {$tableName} ' ENGINE = 'InnoDB'");

问题已经回答了,但希望这能帮助到其他人。

这个错误发生在我身上,因为我首先在迁移表中创建了外键,然后该键才作为主键存在于它的原始表中。按照运行migrate:make后生成的文件名所指示的顺序执行迁移。例如2014年_05_10_165709_create_student_table.php。

解决方案是将具有外键的文件重命名为比具有主键的文件更早的时间,如本文所推荐的:http://forumsarchive.laravel.io/viewtopic.php?id=10246

我想我还必须添加$table->engine = 'InnoDB';

在自动创建的create_users_table迁移更改$table->id();表- >增加美元(id);。为我做了这个技巧,希望这对你有帮助!