22

Can anybody help me to solve this problem?

There are 3 tables with 2 foreign keys:

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

Schema::create('firms', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title')->nullable();
    $table->integer('user_id')->unsigned()->nullable();
    $table->foreign('user_id')->references('id')->on('users');
    $table->timestamps();
});

Schema::create('jobs', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title')->nullable();
    $table->integer('firm_id')->unsigned()->nullable();
    $table->foreign('firm_id')->references('id')->on('firms');
    $table->timestamps();
});
                    

Error after running migration:

[Illuminate\Database\QueryException]
  SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
   (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter ta
  ble `firms` add constraint `firms_user_id_foreign` foreign key (`user_id`)
  references `users` (`id`))

  [PDOException]
  SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
   (errno: 150 "Foreign key constraint is incorrectly formed")
Jsowa
  • 9,104
  • 5
  • 56
  • 60
Yrtymd
  • 433
  • 2
  • 5
  • 16
  • Sorry, it's not working: Schema::create('firms', function (Blueprint $table) { $table->increments('id')->unsigned(); Schema::create('jobs', function (Blueprint $table) { $table->increments('id'); $table->integer('firm_id')->unsigned(); $table->foreign('firm_id')->references('id')->on('firms'); – Yrtymd Nov 29 '16 at 11:42
  • and this is not working too: Schema::create('firms', function (Blueprint $table) { $table->increments('id'); Schema::create('jobs', function (Blueprint $table) { $table->increments('id'); $table->integer('firm_id'); $table->foreign('firm_id')->references('id')->on('firms'); – Yrtymd Nov 29 '16 at 11:42

17 Answers17

51

In case of foreign keys, the referenced and referencing fields must have exactly the same data type.

You create the id fields in both users and firms as signed integers. However, you create both foreign keys as unsigned integers, therefore the creation of the keys fail.

You need to either add the unsigned clause to the id field definitions, or remove the unsigned clause from the foreign key fields.

Shadow
  • 33,525
  • 10
  • 51
  • 64
  • 4
    great, it helped me. – Bhaumik Pandhi Sep 13 '17 at 16:03
  • 9
    Forget about every other thing said this is important `the referenced and referencing fields must have exactly the same data type.` I was nearly going to hang myself. Thanks mate. – Temitayo Mar 04 '19 at 11:17
  • i had this error and i used correct `unsignedBigInteger` for foreign key so but this error show again . we have to sure about `enableForeignKeyConstraints` . i used this `Schema::enableForeignKeyConstraints();` – nasrin.mkh Dec 08 '20 at 05:31
46

This answer is not better than the six answers before it but it is a more comprehensive answer on what causes laravel-errno-150-foreign-key-constraint-is-incorrectly-formed and how to fix specifically for laravel.

1) Spelling : often at times a wrong spelling of the referenced column name or referenced table name can throw up this error and you won't know as the error trace is not very descriptive.

2) Unique : the referenced column must be unique or indexed either by adding ->primary() or adding ->unique() or adding ->index() to the column definition in your migration.

3) Data type : the referenced and referencing fields must have exactly the same data type. this can not be stressed enough.

  • for bigincrements expected data type is bigInteger('column_name')->unsigned();

  • for increments expected is integer('column_name')->unsigned(); etc.

4) Remnants : when this error occurs it does not mean that the table is not migrated rather it is migrated but the foreign key columns are not set and it is not added to the migration table hence running php artisan migrate:reset will remove other tables except the faulty tables, so a manual drop of the faulty table is recommended to avoid further errors.

5) Order : this is often the most usual cause of this error the table being referenced must be created or migrated before the reference table else artisan wont find where to integrate the foreign key. to ensure an order for the migration process rename the migration file example:

  • Table A:2014_10_12_000000_create_users_table.php and
  • Table B:2014_10_12_100000_create_password_resets_table.php

This indicates that Table A will always come before Table B to change that, i will rename Table B to 2014_10_11_100000_create_password_resets_table.php now it will migrate before Table A.

6) Enable Foreign Key : if all else fails then add Schema::enableForeignKeyConstraints(); inside your function up() before your migration code example:

class CreateUsersTable extends Migration
{
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
    Schema::enableForeignKeyConstraints();
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
 }

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

To read more see laravel foreign key and laravel migrations

Mention any more fixes that i missed in the comments thanks.

Bobby Axe
  • 1,491
  • 13
  • 29
  • 1
    Thank you for your thorough explanations. The first bullet point of number 3 worked for me! – Shenole Latimer May 20 '19 at 01:01
  • 1
    `Unique : the referenced column must be unique` - this is not necessarily true in MySQL (remember, the error message got nothing to do with laravel, it comes from MySQL). This requirement used to be true for NDB table type, v8.0 aligned NDB requirement with innodb's. For the widely used innodb table type the requirement is that the referenced column must be indexed. – Shadow Jun 11 '19 at 11:41
  • 1
    If you want a more comprehensive list of possible causes, then see the following SO question: https://stackoverflow.com/questions/1457305/mysql-creating-tables-with-foreign-keys-giving-errno-150 – Shadow Jun 11 '19 at 11:43
  • 1
    Thank you so much. #3 Worked like a charm – Jovanni G Dec 27 '19 at 21:50
  • 1
    Order was my mistake. Thanks . – Ani Jan 06 '20 at 19:52
  • 1
    You are a hero. The main problem was the order; just changed the filename's date and it worked like a charm. THANK YOU. – RickJo Aug 26 '21 at 00:45
8

Most of the time this kind of error occurs due to the datatype mismatch on both the table.

Both primary key table & foreign key table should use same datatype and same option.

For example:

users

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

orders

 Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('product_id')->unsigned();
            $table->foreign('product_id')->references('id')->on('products');
            $table->bigInteger('user_id')->unsigned();
           $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

            $table->timestamp('added_on');
        });

On above example, I am trying to assign foreign key to users table from order table but I have bigInteger datatable in order table while in user table, I have simple integer. That's why it's generated this kind of error.

Also, If you have used unsigned(), nullable() etc options with primary or foreign key then you should use same at both the place.

Mayank Dudakiya
  • 3,635
  • 35
  • 35
4

For PHP laravel 5.8 use unsigned modifier in this format

$table->unsignedBigInteger('user_id');

drop all tables in the database and run the migration again

cbuchart
  • 10,847
  • 9
  • 53
  • 93
Tino Tadez
  • 41
  • 2
  • Note: it appears that the migration table being referenced in a foreign key MUST be already created. Otherwise, I get "errno 150 Foreign key constraint is incorrectly formed". – Jacob Jul 15 '20 at 18:54
2
  • users
  • cashier refers users
  • student refers cashier

In addition when declaring foreign keys in laravel all tables your are referring must be on the top. In this case you can use "->unsigned()" modifier..

2

If the reference table primary key is in BigIcrements then Use the BigInteger for foreign key also like below

Table ATable

public function up()
{
    Schema::create('a_tables', function (Blueprint $table) {
        $table->bigIncrements('id');
   }
}

TABLE BTable

public function up()
{
    Schema::create('b_tales', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('a_tables_id')->unsigned();
     $table->foreign('a_tables_id')->references('id')->on('a_tables')->onDelete('cascade');
   }
}
Sayeed roshan
  • 179
  • 2
  • 5
2
public function up() {     Schema::create('companies', function (Blueprint $table) {         $table->bigIncrements('id');         $table->string('name');         $table->text('address');         $table->string('tel1');         $table->string('tel2');         $table->integer('owner');         $table->unsignedBigInteger('access_id');         $table->string('depot_number')->default(2);         $table->timestamps();           $table->foreign('access_id')->references('id')->on('accesses')             ->onDelete('cascade');     }); } 

public function up() {     Schema::create('accesses', function (Blueprint $table) {         $table->bigIncrements('id');         $table->string('type');         $table->string('description');         $table->timestamps();     }); } 

In your database/migrations folder, sort by name. Then make sure create_accesses_table is before create_companies_table here:

here

Netwons
  • 1,170
  • 11
  • 14
1

we are table villes:

Schema::create('villes', function (Blueprint $table) {
            $table->bigIncrements('idVille'); // bigIncrement(8 bits)
            $table->string('nomVille');
            $table->timestamps();
        });

foreign key in table users for exemple :

Schema::table('users', function (Blueprint $table) {
            $table->bigInteger('ville_idVille')->unsigned()->after('tele');
            $table->foreign('ville_idVille')->references('idVille')->on('villes');
        });
Saad Tejda
  • 11
  • 2
0

if you set referencing fields and be have exactly the same data type but error exists you can change date migration file just its working

Ehab Elzeny
  • 234
  • 4
  • 6
0

I tried all the answers provided in this thread.

Nothing worked.

Then I discovered I forgot to remove the "migrations" table in phpMyadmin.

I removed all tables from phpMyAdmin but the migrations table. That's why the error persisted again and again.

Mz1907
  • 625
  • 4
  • 10
0

Well this answer is related to Laravel 7.x. So the error:

errno: 150 "Foreign key constraint is incorrectly formed"

can occur due many reason while migrating the migrations. The one common reason that I am familiar about is order of migration.

Lets say we have two table "users" and "roles", and "users" table have a foreign key referring the "id" column on "roles" table. So make sure that "roles" is migrated before "users" table.

So order of migration is important. Its obvious as it does not make sense for MySQL to refer to "id" column of unknown table.

Second reason is wrong data type. In laravel 7.x we use "id()" method for primary key. So make sure that the intended foreign key (in my case "role_id" in "users" table) is of "bigInteger" and is "unsigned".

Here my code:

Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('slug')->nullable();
        $table->timestamps();
    });


Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->bigInteger("role_id")->unsigned();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();

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

public function down()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropForeign('users_role_id_foreign'); 
    });
    Schema::dropIfExists('users');
}

So in the above code I had to migrate the "roles" table first then the "users" table. So MySQL can create foreign key for the roles table.

What is do is I move the child migration (migration having foreign key) to temporary folder. And restore it after migrating parent migration (in my case "roles" table and then migrate the child migration ("users" migration).

And as side tip: while dropping the dependent migration (migration containing foreign key) first drop the foreign key first. And Laravel uses specific naming convention while dropping foreign key "<table_name>_<foreign_key>_foreign".

So happy coding and be ready for Ground breaking release of PHP 8.

Gursewak Singh
  • 642
  • 1
  • 7
  • 20
  • thanks for this, the spot that really made it click was realizing the forgien key table needs to be migrated *before* when its called. duh! ty – Mike Lucid Feb 03 '21 at 22:23
0

Here the main concept is you have to ensure same type of primary key and foreign key. For example, Let your 1st table migration is

public function up()
{
    Schema::create('chapters', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->timestamps();
    });
}

Then your 2nd table migration will be

public function up()
{
    Schema::create('classifications', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->unsignedBigInteger('chapter_id');
        $table->timestamps();
        $table->foreign('chapter_id')->references('id')->on('chapters')->onDelete('cascade');
    });
}

Here "id" in "chapter" table and "chapter_id" in " classifications " table are same and that is "unsignedBigInteger".

Again if you get error then change " $table->id(); " in "chapter" table by " $table->bigIncrements('id'); ".

Hope this will help you

Lokman Hosen
  • 342
  • 5
  • 6
0

for the laravel 7 migration error as

("SQLSTATE[HY000]: General error: 1005 Can't create table laraveltesting.reviews (errno: 150 "Foreign key constraint is incorrectly formed")")

order of migration is most important so parent table should be migrated first then only child Image 1:migration order while getting error


        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('detail');
            $table->float('price');
            $table->integer('stock');
            $table->float('discount');
            $table->timestamps();
        });
 Schema::create('reviews', function (Blueprint $table) {
            $table->id();
            $table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
            $table->string('customer');
            $table->text('review');
            $table->integer('star');

            $table->timestamps();
        });

this causes the error while migrating this can be resolved by changing the order of migration by renaming the migration as shown in image 2 from the image 1. books table should be migrated first then only the review table should be migrated

Image 2:Order of migration for the successful migration

0

if you get error change $table->id()(references) by $table->increments('id')

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

worked with me after all Efforts

delete (user table) from both database and (migration table)
then "uncomment" your foreign key Relations
example : $table->string('pass1'); $table->foreign('pass1')->references('email')->on('abs');
then run : php artisan migrate well run successfully enter image description here

enter image description here

0

sometime your query syntax is true but this error is occur because you create your table unorderly if you want to make relation between table let's suppose you wanna a create many to many relationship between "user" and "role" table for this you should migrate user and role table first then create "role_user" table else you face error like this. For more details check my screenshot. enter image description here

0

in laravel 9 i got same error while creating foreign key for my posts table

 SQLSTATE[HY000]: General error: 1005 Can't create table `wpclone`.`posts` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `posts` add constraint `posts_author_id_foreign` foreign key (`author_id`) references `users` (`id`) on delete restrict)

and my table looks like this:

    Schema::create('posts', function (Blueprint $table) {
                $table->id();
                $table->integer('author_id')->unsigned();
                $table->foreign('author_id')->references('id')->on('users')->onDelete('restrict');
                $table->string('title');
});

after i found solution that in laravel 9 unsigned modifier in this format work well

$table->unsignedBigInteger('author_id');

and my error was solve. hope this will help you. Thanks