web-dev-qa-db-ja.com

Laravel migration(errno:150 "外部キー制約の形式が正しくありません")

私には注文表があり、sell_shipping_labelsを外部として参照するorders.idがあります。しかし、Laravel移行を実行すると、恐ろしいエラーコードが表示されます。

[Illuminate\Database\QueryException]
SQLSTATE [HY000]:一般エラー:1005テーブルcheapbooks_test.#sql-b5b_b2aを作成できません(errno:150 "外部キー制約の形式が正しくありません")(SQL:alter table sell_shipping_labels制約の追加sell_shipping_labels_order_id_foreign外部キー(order_id)参照ordersid))

[Doctrine\DBAL\Driver\PDOException]
SQLSTATE [HY000]:一般エラー:1005テーブルcheapbooks_test.#sql-b5b_b2aを作成できません(errno:150 "外部キー制約の形式が正しくありません")

これは私のordersテーブルスキーマです。

   Schema::create('orders', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id');
        $table->integer('book_id');
        $table->integer('status_id');
        $table->double('payment_amount')->nullable();
        $table->timestamp('received_at')->nullable();
        $table->timestamp('paid_at')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });

そして、これは私のsell_shipping_labelsスキーマです:

Schema::create('sell_shipping_labels', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('order_id');
        $table->string('shippo_object_id');
        $table->string('label_url');
        $table->string('tracking_url');
        $table->string('tracking_number');
        $table->timestamp('arrived_at');
        $table->timestamps();
        $table->softDeletes();

        $table->foreign('order_id')->references('id')->on('orders');
    });
}

今、私は問題を解明しようとして、インターネットをひっくり返しました。この問題に関するすべての投稿は、注文テーブルを作成する必要があるという事実に言及しています[〜#〜] [〜#〜]テーブルこれには外部キーがありますが、ファイルの順序が正しいため、これは問題ではありません。

12
FrenchMajesty

increments()は符号なし整数列を作成するため、外部キー列も符号なし整数として定義する必要があります。

$table->unsignedInteger('order_id');

または:

$table->integer('order_id')->unsigned();

https://laravel.com/docs/5.5/migrations#foreign-key-constraints

26
Alexey Mezenin

外部キーは「unsignedBigInteger」である必要があり、次のように修正されます。

$table->unsignedBigInteger('user_id');

$table->foreign('user_id')->references('id')->on('users');
11
user10428851

主キーと外部キーは同じデータ型である必要があります

主キーが符号なしbig_integerを使用している場合、外部キーも符号なしbig_integerを使用する必要があります。

laravel= 5.8は新しい移行を生成するときにデフォルトでbigIncrementsを使用します(この pull request を参照)、foreign keybig_incrementであることを確認する必要がありますまたは、エラーが発生します。

テーブルusers

Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');

    ...

}

テーブルorders

Schema::create('orders', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id');

    ...

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

お役に立てれば。

5
Nurul Huda

Laravel 5.8.3には$table->bigIncrements('id');が付属しています

に変更する

$table->increments('id');
$table->integer('order_id')->unsigned();
4

私も同じエラーを受け取っていました。 sersテーブルでやっていることは、

$table->unsignedInteger('role_id')->default(2); table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');

しかし、ユーザーテーブルを作成した後、ロールテーブルを作成しました。そのため、ユーザーテーブルのファイル名の日付の前に、役割移行ファイルの名前の日付を編集しました。このような、

2013_01_22_091213_create_roles_table.php
2014_10_12_000000_create_users_table.php

そして最後に動作します。この問題が発生する可能性があります。だから、私はそれを投稿しました。

2
Anand Mainali

laravel 5.8.xを使用してこれを見ている人には、これを変更してこれを修正しました

$table->unsignedInteger('foreign_id');

これに

$table->unsignedBigInteger('foreign_id');

これは、bigIncrementsを使用しているためです。代わりに、関係の両側で、bigIncrementsからインクリメントへのチャンスを削除できます。

2
Dave

移行の順序を確認します。 migrateコマンドが注文表の前にsell_shipping_labels表を作成しようとしている場合、これはMySQLで発生します。最も古いものから新しいものへの移行日を作成しているようです。つまり、参照しようとしているテーブルにorder_idが存在する必要があります。

同じ問題に直面したため、移行の作成日を変更します。

1
Abid Shah
  1. 移行ファイルは、親の移行が最初になり、次に移行キーが外部キーを持つように作成する必要があります。
  2. 外部キーと他のテーブルのプライマリIDには、まったく同じプロパティが必要です。プライマリIDが増分の場合、外部キーをinteger( 'xxx_id')-> unsigned()にします。
1
Ayenew Yihune

同じ問題が発生し、データベースタイプをinnoDBに設定する問題を修正しました

移行前に作成されたテーブル(「レガシーシステムからのMyISAMおよび移行されたもの」はデフォルトでinnoDBであるため、私の場合はテーブルタイプの混在が問題でした。

1
alker

回答をマークしたものが機能しなかった場合:

テーブルエンジンを確認します。私の場合、InnoDBソーステーブルのMyISAMテーブルで参照していました。参照テーブルエンジンをInnoDBに変更した後、機能しました!

1
Erfun

それでも問題が解決しない場合は、試してください。最後に関連付けられたテーブルを作成する必要があります。

最初に注文を作成し、sell_shipping_labelsテーブルを作成した後、

この問題を解決するには、CategoryおよびUsersの移行ファイルの名前を、食事前の移行ファイルを作成する食事前の移行ファイルに変更する必要があります。

0

今日も同じ問題に直面しました。私のlaravelバージョンは5.8.29です。以下を実行することで問題を解決しました。

$table->bigIncrements('id'); //current table primary key and id
$table->unsignedBigInteger('user_id'); // foreigh key
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

これがうまくいくことを願っています。

0
Hossni Mubarak

今日、この問題に直面しました。参照キーと外部キーの同じデータ型、データベースエンジンでの同じ照合、laravel config(database.php)、移行の日付順、その他の可能性のあるミスなど、提案されたすべてのソリューションをチェックしましたが、私の解決策でした!最後に見つけたのは、移行を行うonUpdateおよびonDeleteの制約でした。

0
[![enter image description here][1]][1]
public function up()
    {
        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();


        });
    }

I changed $table->bigIncrements('id') to $table->Increments('id')
For this user_id of files table become same integer type as user table field id. After this command worked.

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



For the second table
 {
        Schema::create('files', function (Blueprint $table) {
            $table->increments('id');

});

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

enter image description here

0
radhason power