web-dev-qa-db-ja.com

SQLSTATE [HY000]:一般エラー:1215外部キー制約を追加できませんLaravel=

artisanを使用して外部キーを作成しようとしていますが、このエラーが表示されます。

[Illuminate\Database\QueryException]                                                                                                                                                                             
  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `comments` add constraint `comments_comment_lot_id_foreign` foreign key (`comment_lot_id`) references `lots` (`lot_id`  
  ) on delete cascade) 

これは私の移行です:

<?php

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

class CreateCommentsTable extends Migration
{

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->text('comment');
            $table->integer('comment_lot_id')->unsigned();
            $table->timestamps();
        });

        Schema::table('comments', function ($table) {
            $table->foreign('comment_lot_id')->references('lot_id')->on('lots')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropForeign(['comment_lot_id']);
        Schema::dropIfExists('comments');
    }
}

ロットテーブルでは、lot_idid as it model Lot.php i add:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Lot extends Model {
    protected $primaryKey = 'lot_id';

}

このエラーを解決するにはどうすればよいですか?

14
Dmitry Malys

以下のルールを移行ファイルに適用します

[1]

親のピボットテーブルは、外部キー参照をサポートするエンジン(InnoDB for mysqlなど)に基づいている必要があります。

移行ファイルで、他の列定義の直前に_$table->engine = “InnoDB”;_を実行します。

laravelは常にMyISAMにデフォルト設定されているため、この行は必須です。

[2]

親の参照列は、主キーまたは一意のキーである必要があります。

親テーブルのこれらの宣言は問題ありません。

$table->increments(“id”);は、列「id」が参照可能であることを意味します

$table->column_type(“column_name”)->unique();は、列「column_name」が参照可能であることを意味します

[3]

ピボットテーブルの列は、参照される親テーブルの列と同じ型である必要があります。

したがって、たとえば、increments(“ id”)を参照するピボットテーブル列は、unsignedInteger型である必要があります。

親テーブルがchar(20)型の場合、それを参照するために使用されるピボットテーブル列もchar(20)型でなければなりません。

上記3つすべてを完了したら、必要に応じて外部キー関係を定義します。

24
korwalskiy

これはあなたにとって問題ではなかったように見えますが、Laravel 5.8で同じエラーに到達し、興味深い問題を見つけました:Laravel今ではデフォルトで 'id '列を単に' increments 'ではなく' bigIncrements 'に変更します。したがって、以前のように' integer 'で参照する代わりに、' bigInteger 'で参照する必要があります。

親テーブルが次のように見える場合:

$table->bigIncrements('id');

次に、子の移行は次のようになります。

$table->bigInteger('parent_id')->unsigned()->index();
$table->foreign('parent_id')->references('id')->on('parent');

これが5.8以降でこの問題に遭遇した人の助けになることを願っています。

13
manley13

引用 この答え:

特定のエラーを見つけるには、これを実行します:

SHOW ENGINE INNODB STATUS;

そしてLATEST FOREIGN KEY ERRORセクションを見てください。

タイプの問題かもしれません。 comment_lot_idは、lot_idとまったく同じタイプでなければなりません。 1つは署名され、もう1つは署名されていない可能性があります。

3
rap-2-h