web-dev-qa-db-ja.com

Laravel移行外部キー制約の形式が正しくありません

DBを移行すると、このエラーが表示されます。以下にコードを示し、移行を実行しようとするとエラーが表示されます。

コード

 public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->string('title');
            $table->string('body');
            $table->string('meal_av');
            $table->timestamps();

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

            $table->foreign('category_id')
                ->references('id')
                ->on('categories')
                ->onDelete('cascade');
        });
    }  

エラーメッセージ

[Illuminate\Database\QueryException]                                         
      SQLSTATE[HY000]: General error: 1005 Can't create table `meal`.`#sql-11d2_1  
      4` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter   
      table `meals` add constraint meals_category_id_foreign foreign key (`catego  
      ry_id`) references `categories` (`id`) on delete cascade) 
23
Muhammad Tareq

@JuanBonnettあなたの質問は、laravelで採用された答えに私を触発しました。ファイル自体の作成時間を考慮せずにプロセスを自動化するため、ワークフローの食事はテーブル(カテゴリ)の前に作成されます)カテゴリの前にスキーマファイル(食事)を作成したからです。

17
Muhammad Tareq

Laravelで新しいテーブルを作成するとき。移行は次のように生成されます。

$table->bigIncrements('id');

代わりに(古いLaravelバージョンで):

$table->increments('id');

bigIncrementsを使用する場合、外部キーはintegerではなくbigIntegerを期待します。したがって、コードは次のようになります。

public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedBigInteger('user_id'); //changed this line
            $table->unsignedBigInteger('category_id'); //changed this line
            $table->string('title');
            $table->string('body');
            $table->string('meal_av');
            $table->timestamps();

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

            $table->foreign('category_id')
                ->references('id')
                ->on('categories')
                ->onDelete('cascade');
        });
    }  

Kiko Sejio のように、incrementsの代わりにbigIncrementsを使用することもできます。

IntegerとBigIntegerの違いはサイズです:

  • int => 32ビット
  • bigint => 64ビット
31
Swooth

外部キーの最後に->unsigned()->index()を追加するだけで機能します

11
geekbro

私にとってはすべてが正しい順序でしたが、それでも動作しませんでした。それから、私はいじることによって、主キーが署名されていない必要があることを発見しました。

//this didn't work
$table->integer('id')->unique();
$table->primary('id');

//this worked
$table->integer('id')->unsigned()->unique();
$table->primary('id');

//this worked 
$table->increments('id');
10
zamppe

移行を順番に作成する必要があります。たとえば、usersrole_id私のrolesテーブルのフィールド

Ifirst役割の移行を開始php artisan make:migration create_roles_table --create=roles

次に、2番目のユーザーの移行php artisan make:migration create_users_table --create=users

php artisan migrationは、作成されたファイルの順序を使用して実行されます2017_08_22_074128_ create_roles_table.phpおよび2017_08_22_134306_ create_users_tableは、実行順序になる日時順序を確認します。

ファイル2017_08_22_074128_create_roles_table.php

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name', 50);
        $table->timestamps();
    });
}

2017_08_22_134306_create_users_table

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('role_id')->unsigned();
        $table->string('name');
        $table->string('phone', 20)->unique();
        $table->string('password');
        $table->rememberToken();
        $table->boolean('active');
        $table->timestamps();
        $table->foreign('role_id')->references('id')->on('roles');
    });
}
5

私の場合、新しいlaravel規則がこのエラーの原因でした。

テーブル作成の単純なスワップによって、idがトリックを行いました。

$table->increments('id'); // ok

、 の代わりに:

$table->bigIncrements('id'); // was the error.

既にLaravel v5.8、これまでこのエラーは発生していません。

5
Kiko Seijo

データ型の不一致の問題について同じメッセージが表示されました。

'id'にbigIncrements()を使用し、それを外部キーとして使用したとき(usedbigInteger())エラーが発生しました。

私は解決策を見つけました、bigIncrements()unsignedBigIntegerを返します。したがって、bigInteger()の代わりにunsignedBigInteger()を使用する必要がありますキー

他の人を助けるかもしれないのでこれを共有する

5
Bashar

外部キー定義で->onDelete('set null')を使用している場合は、外部キーフィールド自体がnullable()であることを確認してください。つまり

//Column definition
$table->integer('user_id')->unsigned()->index()->nullable(); //index() is optional

//...
//...

//Foreign key 
$table->foreign('user_id')
      ->references('id')
      ->on('users')
      ->onDelete('set null');
4
aphoe

移行はトップダウンで作成する必要があります。

最初に、誰にも属さないテーブルの移行を作成します。

次に、前のものに属するテーブルの移行を作成します。


テーブルエンジンの問題に対する簡略化された回答:

テーブルのストレージエンジンを設定するには、スキーマビルダーでエンジンプロパティを設定します。

Schema::create('users', function ($table) {
    $table->engine = 'InnoDB';

    $table->increments('id');
});

From Laravel Docs: https://laravel.com/docs/5.2/migrations

4
Manuel Azar

ここに着陸した人の助けになるかもしれません:私はちょうど同じ問題を経験しましたが、私の場合は、外部キー列の前に外部キー列に(複合)一意制約が設定されていました。 「独自の」声明を「外国の」声明の後に配置することで問題を解決しました。

作品:

$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
$table->unique(['step_id','lang']);

動作しません:

$table->unique(['step_id','lang']);
$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
2
Matthias

私の場合、問題は参照されたテーブルの1つがInnoDBで、もう1つがMyISAMであったことでした。

MyISAMは外部キー関係をサポートしていません。

したがって、今ではbothテーブルはInnoDBです。問題が解決しました。

2
nwrman

移行ファイルの作成順序は並べ替えられ、外部キーは他のテーブルの主キーとまったく同じプロパティを持つ必要があります。

1
Ayenew Yihune

フィールドに-> nullable()を追加し、参照しているすべてのフィールドが実際に存在することを確認します。

0
Rafael Xavier

ララベル5.8

外部キーの列でnsignedBigIntegerを使用して、外部キーのデータ型の不一致の問題を回避します。例では、2つのテーブルquestionsおよびrepliesがあると仮定します。
質問表は次のようになります。

 public function up()
    {
        Schema::create('questions', function (Blueprint $table) {
            $table->bigIncrements('id');
             $table->text('body');
             $table->integer('user_id')->unsigned();
            $table->timestamps();
        });
    }

返信テーブルは次のようになります。

public function up()
{
    Schema::create('replies', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->text('body');
        $table->unsignedBigInteger('question_id');
        $table->integer('user_id')->unsigned();
        $table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
        $table->timestamps();
    });
}
0
Hussam Adil

これは、参照フィールドと参照フィールドのデータ型がまったく同じであることが重要です。

0
Marek