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)
@JuanBonnettあなたの質問は、laravelで採用された答えに私を触発しました。ファイル自体の作成時間を考慮せずにプロセスを自動化するため、ワークフローの食事はテーブル(カテゴリ)の前に作成されます)カテゴリの前にスキーマファイル(食事)を作成したからです。
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の違いはサイズです:
外部キーの最後に->unsigned()->index()
を追加するだけで機能します
私にとってはすべてが正しい順序でしたが、それでも動作しませんでした。それから、私はいじることによって、主キーが署名されていない必要があることを発見しました。
//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');
移行を順番に作成する必要があります。たとえば、users
にrole_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');
});
}
私の場合、新しいlaravel規則がこのエラーの原因でした。
テーブル作成の単純なスワップによって、id
がトリックを行いました。
$table->increments('id'); // ok
、 の代わりに:
$table->bigIncrements('id'); // was the error.
既にLaravel v5.8
、これまでこのエラーは発生していません。
データ型の不一致の問題について同じメッセージが表示されました。
'id'にbigIncrements()を使用し、それを外部キーとして使用したとき(usedbigInteger())エラーが発生しました。
私は解決策を見つけました、bigIncrements()はunsignedBigIntegerを返します。したがって、bigInteger()の代わりにunsignedBigInteger()を使用する必要がありますキー
他の人を助けるかもしれないのでこれを共有する
外部キー定義で->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');
移行はトップダウンで作成する必要があります。
最初に、誰にも属さないテーブルの移行を作成します。
次に、前のものに属するテーブルの移行を作成します。
テーブルエンジンの問題に対する簡略化された回答:
テーブルのストレージエンジンを設定するには、スキーマビルダーでエンジンプロパティを設定します。
Schema::create('users', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
});
From Laravel Docs: https://laravel.com/docs/5.2/migrations
ここに着陸した人の助けになるかもしれません:私はちょうど同じ問題を経験しましたが、私の場合は、外部キー列の前に外部キー列に(複合)一意制約が設定されていました。 「独自の」声明を「外国の」声明の後に配置することで問題を解決しました。
作品:
$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');
私の場合、問題は参照されたテーブルの1つがInnoDBで、もう1つがMyISAMであったことでした。
MyISAMは外部キー関係をサポートしていません。
したがって、今ではbothテーブルはInnoDBです。問題が解決しました。
移行ファイルの作成順序は並べ替えられ、外部キーは他のテーブルの主キーとまったく同じプロパティを持つ必要があります。
フィールドに-> nullable()を追加し、参照しているすべてのフィールドが実際に存在することを確認します。
ララベル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();
});
}
これは、参照フィールドと参照フィールドのデータ型がまったく同じであることが重要です。