laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
31.85k stars 10.79k forks source link

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint #27717

Closed jackwander closed 5 years ago

jackwander commented 5 years ago

Description:

My code for inserting FK is working on 5.7 but not in 5.8.

driesvints commented 5 years ago

I'll need more info and/or code to debug this further. Please post relevant code like models, jobs, commands, notifications, events, listeners, controller methods, routes, etc. You may use https://paste.laravel.io to post larger snippets or just reply with shorter code snippets. Thanks!

jackwander commented 5 years ago

I'll need more info and/or code to debug this further. Please post relevant code like models, jobs, commands, notifications, events, listeners, controller methods, routes, etc. You may use https://paste.laravel.io to post larger snippets or just reply with shorter code snippets. Thanks!

Sorry my bad.

Here is the sequence of my migration.

Users Table

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

Roles

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

Inserting FK to Users

        Schema::table('users', function (Blueprint $table) {
            $table->unsignedInteger('role_id')->nullable();
            $table->foreign('role_id')
                ->references('id')
                ->on('roles');
        });
staudenmeir commented 5 years ago

Are both tables using the InnoDB engine?

driesvints commented 5 years ago

What error are you getting exactly?

jackwander commented 5 years ago

Are both tables using the InnoDB engine?

Yes they're both InnoDB engine.

What error are you getting exactly?

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

What's the difference of bigIncrements to increments? Coz in 5.7 the id per migration create is increments but in 5.8 it's bigIncrements.

driesvints commented 5 years ago

@jackwander https://github.com/laravel/framework/pull/26472

michaeldzjap commented 5 years ago

I am running into the same problem here. I have a migration that adds a foreign key, referencing the id column on the users table and after upgrading to Laravel 5.8 this no longer works. This is the up of my original migration:

public function up()
{
    Schema::create('two_factor_auths', function (Blueprint $table) {
        $table->string('id')->nullable();
        $table->unsignedInteger('user_id');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->timestamps();
    });
}

But then running php artisan migrate -v on a freshly created db (InnoDB) results in:

  Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `two_factor_auths` add constraint `two_factor_auths_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)

  at /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668| 

  Exception trace:

  1   PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint")
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  3   Illuminate\Database\Connection::Illuminate\Database\{closure}("alter table `two_factor_auths` add constraint `two_factor_auths_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade", [])
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:657

  4   Illuminate\Database\Connection::runQueryCallback("alter table `two_factor_auths` add constraint `two_factor_auths_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade", [], Object(Closure))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:624

  5   Illuminate\Database\Connection::run("alter table `two_factor_auths` add constraint `two_factor_auths_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade", [], Object(Closure))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Connection.php:459

  6   Illuminate\Database\Connection::statement("alter table `two_factor_auths` add constraint `two_factor_auths_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade")
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php:97

  7   Illuminate\Database\Schema\Blueprint::build(Object(Illuminate\Database\MySqlConnection), Object(Illuminate\Database\Schema\Grammars\MySqlGrammar))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php:264

  8   Illuminate\Database\Schema\Builder::build(Object(Illuminate\Database\Schema\Blueprint))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php:165

  9   Illuminate\Database\Schema\Builder::create("two_factor_auths", Object(Closure))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:237

  10  Illuminate\Support\Facades\Facade::__callStatic("create")
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/michaeldzjap/twofactor-auth/src/database/migrations/2017_05_26_102832_create_two_factor_auths_table.php:21

  11  CreateTwoFactorAuthsTable::up()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:360

  12  Illuminate\Database\Migrations\Migrator::Illuminate\Database\Migrations\{closure}()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:367

  13  Illuminate\Database\Migrations\Migrator::runMigration(Object(CreateTwoFactorAuthsTable), "up")
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:178

  14  Illuminate\Database\Migrations\Migrator::runUp("/home/vagrant/code/laravel-two-factor-authentication-example/vendor/michaeldzjap/twofactor-auth/src/database/migrations/2017_05_26_102832_create_two_factor_auths_table.php")
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:147

  15  Illuminate\Database\Migrations\Migrator::runPending([])
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:96

  16  Illuminate\Database\Migrations\Migrator::run([])
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php:71

  17  Illuminate\Database\Console\Migrations\MigrateCommand::handle()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32

  18  call_user_func_array([])
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32

  19  Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90

  20  Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34

  21  Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Container/Container.php:580

  22  Illuminate\Container\Container::call()
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Console/Command.php:183

  23  Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/symfony/console/Command/Command.php:255

  24  Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Console/Command.php:170

  25  Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/symfony/console/Application.php:901

  26  Symfony\Component\Console\Application::doRunCommand(Object(Illuminate\Database\Console\Migrations\MigrateCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/symfony/console/Application.php:262

  27  Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/symfony/console/Application.php:145

  28  Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Console/Application.php:90

  29  Illuminate\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:122

  30  Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
      /home/vagrant/code/laravel-two-factor-authentication-example/artisan:37

Changing from $table->unsignedInteger('user_id'); to $table->bigIncrements('user_id'); in my migration makes it work. I can then successfully run the migration. Maybe this will help.

mfn commented 5 years ago

I think it's related to:

Maybe I'm mistaken, but these are the only changes which come up to me as having the potential creating a column type mismatch between two tables.

michaeldzjap commented 5 years ago

What would be the advice for people upgrading from < 5.8 to 5.8 though? Should they ideally change their id col on users to bigIncrements? Or should / can they safely keep using increments?

And with regards to libraries that use migrations that reference id on users this becomes a little complicated as well. If I don't update the affected migration then my library becomes incompatible for users that start a fresh Laravel 5.8 project. If I do update the affected migration my library becomes incompatible for users that upgrade from < 5.8 to 5.8 (and hence don't change from increments to bigIncrements) and decide they want to start using my lib (hence having to run the original migration which now uses bigIncrements). Not seeing a clean solution out of this. Perhaps someone has an idea?

ekam230 commented 5 years ago

I have this trouble too.

i fix this trouble

change in migration users

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

on

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

michaeldzjap commented 5 years ago

Coming back to this. I've managed to sort of solve my problems, but it feels very hacky. I basically check the type of id on users before creating my user_id column:

if (DB::getDoctrineSchemaManager()->listTableDetails('users')->getColumn('id')->getType() instanceof \Doctrine\DBAL\Types\IntegerType) {
    $table->increments('user_id');
} else {
    $table->bigIncrements('user_id');
}

This is not great because:

  1. There now is a dependency on the doctrine/dbal package. It was the only easy way I could figure out to get the type of the id column on users. If someone else knows another way, please share.
  2. I don't think it is appropriate to use this sort of conditional logic in a migration file, but I see no other solution.

I realise that this is perhaps not going to be received well, but is there any way this bigIncrements change on users can be reverted? I have read the provided links by @mfn and @driesvints, and I can understand why the change was considered. However, I also think perhaps the consequences of this change on an existing code base have been somewhat miscalculated.

jackwander commented 5 years ago

Hi guys, I've solved this by changing all my migration's id from bigIncrements to increments. So every time i generate a new migration php artisan make:migration NAME --create=table_name i just change the bigIncrements to increments so that i can set a FK constraint.

devcircus commented 5 years ago

or change your foreign keys to bigintegers. This is in line with where the framework is headed.

heloufir commented 5 years ago

Hello, I just had the same issue with the laravel 5.8.2 version, I did what @jackwander says

"I've solved this by changing all my migration's id from bigIncrements to increments"

To make it works, just for your information, I changed my foreign keys to bigInteger and unsignedBigInteger but it doesn't work either.

snetts commented 5 years ago

Hello, What worked for me is changing from the column from integer to bigInteger and placing it in the table update section as follows:

Schema::table('services', function($table) { $table->bigInteger('business_id')->unsigned()->index(); $table->foreign('business_id')->references('id')->on('businesses')->onDelete('cascade'); });

Thanks for you help guys.

driesvints commented 5 years ago

I'm closing this because as noted, foreign keys need to be of the same type. Please see the upgrade guide: https://laravel.com/docs/5.8/upgrade

fridzema commented 5 years ago

At the moment of release this was not documented in the release notes... Why is it even changed?

~99% of the people don't fill the database with 2147483647 records. When you go above this amount i hope you know what you are doing and can easily change this yourself.

Now it is default for all users with zero advantages in my opinion.

Some examples why this is so bad: http://ronaldbradford.com/blog/bigint-v-int-is-there-a-big-deal-2008-07-18/ https://www.mssqltips.com/sqlservertip/5115/compare-sql-server-table-join-performance-for-int-vs-bigint-vs-guid-data-types/

slymbo commented 5 years ago

Hello, Because they new version of Laravel using by default use BIGINT for the primary key"id", then to resolve the problem of foreign key you need to create the same type in the child table.

public function up() { Schema::create('yourTableName', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('fieldName'); /* The foregin Key take the same type of primary key for the mother table (user) */ $table->unsignedBigInteger('user_id');

        $table->timestamps();

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

I hope this help you and thanks ;)

nmichalakis commented 5 years ago

@arabrain solution did the trick (thank you!). I have lost like 2hrs wandering about what i was doing wrong and as a new laravel guy this was really frustrating.

prateekvarma commented 5 years ago

It's just a datatype conflict. Either change your bigIncrements to increments... or change your foreign key from integer to bigInteger

saitama3020 commented 5 years ago

I fix it by changing foreign key from unsignedInteger to unsignedBigInteger

LMCom commented 5 years ago

or change your foreign keys to bigintegers. This is in line with where the framework is headed.

Can you elaborate, please? I googled and read some stuff about big ints vs. int. I didn't see anybody writing some kind of justification, why bigIncrements() should become the default for Laravel. I didn't even see somebody question it. The only advantage, I currently see, is the bigger value range. This advantage is rarely relevant, I guess? I am always aware, that I can only get about 4 billion ids with a 4-byte unsigned int. I am able to make the conscious decision to use a slower and more space consuming 8-byte unsigned int, if necessary.

mfn commented 5 years ago

The point is: when you realize you need a bigger space, it's probably too late. Upscaling such a type without a downtime is not fun. Or worse: running out of IDs 💥

If you are conscious about your schema, you don't rely on the skeleton but use the datatypes appropriate for your project.

LMCom commented 5 years ago

The point is: when you realize you need a bigger space, it's probably too late. Upscaling such a type without a downtime is not fun. Or worse: running out of IDs 💥

Absolutely. I am very cautious and don't even count on my experience, when deciding, what datatype to use. You cannot always extrapolate the future from your experience. So I just look at reality and think for example "So we have a few thousand companies as customers. There are 8 billion people on earth. An int would be enough, if every second person had a company AND was our customer."

There are an estimated 200 million companies worldwide (https://datapo.com/news/how-many-companies-are-there-in-the-world/).

This, of course, is a specific example. There are very few cases, where I needed a bigIncrement. And my main point is: I am pretty sure, that in the vast majority of cases an int would be the more sensible choice - and a sensible choice should be the default.

Often, I make small tables with categories of some sort. Even a tinyint could be oversized for that. And I assume, many people already just take an int without thinking. Well, if we ever reach more than 4 billion genders, joke will be on me. ;)

If the default bigIncrement is not driven by real world applications, but by "where the framework is headed", then I question that development and don't quite get, what the plan is.

devcircus commented 5 years ago

I feel like this was a decision that bled over from the Rails community as they made this change in Rails 5.1. There's a lot of discussion for or against the change if you google it. Here is a brief summary. Seems to make sense.

It's not about having billions of users but billions of rows in a table. I think it was the right move for the framework to make. Plus it's just a stub change, you can make it whatever you want if it doesn't work for your app.

cedlinx commented 5 years ago

I feel like this was a decision that bled over from the Rails community as they made this change in Rails 5.1. There's a lot of discussion for or against the change if you google it. Here is a brief summary. Seems to make sense.

It's not about having billions of users but billions of rows in a table. I think it was the right move for the framework to make. Plus it's just a stub change, you can make it whatever you want if it doesn't work for your app.

I think this wraps it up pretty nicely

cedlinx commented 5 years ago

I would just add

Hello, I just had the same issue with the laravel 5.8.2 version, I did what @jackwander says

"I've solved this by changing all my migration's id from bigIncrements to increments"

To make it works, just for your information, I changed my foreign keys to bigInteger and unsignedBigInteger but it doesn't work either.

In my case (Laravel 5.8), what worked was doing BOTH of these:

  1. change foreign keys to bigInteger
  2. make sure foreign keys are unsigned.

Either of these examples worked for me:

  1. unsignedBigInteger('user_id');
  2. bigInteger('user_id')->unsigned();

Hope this helps someone

jicksonjohnson commented 5 years ago

I experienced the same issue. Solution I found by changing the order of migration files.

Imagine the case of posts and comments, we probably have to add the "foreign" on comments table with reference to post_id in posts table. In order to assign this foreign key on comments, posts table has to present first. ( on my case, I have resource and files. files has resource_id as foreign key )

On my case, I created migration file for comments first. After I changed the order, everything works fine. I just renamed the filed by interchanging the number in it.

image

Correct me if I am wrong.

kaythinks commented 4 years ago

Using bigInteger instead of integer solved it for me.

feisalramar commented 4 years ago

This usually happen because of the type mismatch for the correct match of the data type will solve the problem..... bigIncrements = unsignedBigInteger and increments = unsignedInteger. this means that when primary key is bigIncrements then use unsignedBigInteger for foreign key.

kaythinks commented 4 years ago

Alright. Thanks.

On Thursday, July 25, 2019, Feisal Ramadhan Ali notifications@github.com wrote:

This usually happen because of the type mismatch for the correct match of the data type will solve the problem..... bigIncrements = unsignedBigInteger and increments = unsignedInteger. this means that when primary key is bigIncrements then use unsignedBigInteger for foreign key.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/laravel/framework/issues/27717?email_source=notifications&email_token=AGVTM67FQEPVUY3BUTS7QPDQBHTTJA5CNFSM4G24NVPKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD22JVWA#issuecomment-515152600, or mute the thread https://github.com/notifications/unsubscribe-auth/AGVTM64SN6RH2RXIUAAST2DQBHTTJANCNFSM4G24NVPA .

subratpalhar92 commented 4 years ago

Add an index on foreign key column

primary table : $table->increments('id');

foreign Table : $table->integer('foreign_key_column_name')->unsigned(); //increments equivalent $table->index(['foreign_key_column_name']);

Schema::table('primary_tablename', function ($table) {
$table->foreign('id') ->references('foreiogn_table')->on('foreign_COLUMN') ->onDelete('cascade'); });

:enjoy..

agm1984 commented 4 years ago

Usually it's bigInt vs int for me, but I just had a situation where I was trying to add foreign keys to tables that didn't exist yet, so changing the order that the migrations run fixed it.

For example, if you have a salmons and a goats table, and you trying to add a foreign key from the transactions table to the ID column in those tables, the migrations for salmons and goats must run first, otherwise you are trying to add foreign keys to tables that don't exist, which makes Laravel mad.

myproyecto commented 4 years ago

Asegurese de borrar manualmente todas las tablas de la bd, despues ejecutar "php artisan cache:clear" y ahi ya podes hacer las migraciones con migrate:refresh

Padrezz commented 4 years ago

For everyone who looks for solution:

Since laravel uses unsigned bigInt for id, you have to use also same for your reference:

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

            $table->bigInteger('user_id')->unsigned();
            // OR
            $table->unsignedBigInteger('user_id');

           //REFERENCE
            $table->foreign('user_id')->references('id')->on('users'); 
        }); 
luhacra commented 4 years ago

change only fo this line:

$table->unsignedBigInteger('user_id');

herickwilke commented 4 years ago

change only fo this line:

$table->unsignedBigInteger('user_id');

Worked! Thanks.

jackwander commented 4 years ago

The solution for this problem is to use the same data type.

Example

Schema::create('users', function (Blueprint $table) {
  $table->bigIncrements('id'); // The data type is Big Integer.
  $table->string('name');
});

Schema::create('posts', function (Blueprint $table) {
  $table->bigIncrements('id');
  $table->string('title');
  $table->unsignedBigInteger('user_id'); //So we must use also a Big Integer Data type.
  $table->foreign('user_id')->references('id')->on('users'); 
});

OR

Schema::create('users', function (Blueprint $table) {
  $table->increments('id'); // The data type is Integer only.
  $table->string('name');
});

Schema::create('posts', function (Blueprint $table) {
  $table->increments('id');
  $table->string('title');
  $table->unsignedInteger('user_id'); //So we must use also an Integer Data type.
  $table->foreign('user_id')->references('id')->on('users'); 
});

take note, everytime we add a FK it must always be unsigned.

stephan-v commented 4 years ago

I understand the reason for this error, but is there no way to add a more descriptive error message here?

himak commented 4 years ago

I have same problem in pivot table with Laravel-5-Generators-Extended.

I changed in pivot table:

$table->integer('item_id')->unsigned()->index();

to

$table->unsignedBigInteger('item_id')->index();

In Items table I have set:

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

torressam333 commented 4 years ago

I was trying to add unsignedInteger('owner_id') as a a foreign key constraint and was getting this issue. In my create_projects_table I just changed this line to unsignedBigInteger and the migrate:fresh command worked after that.

modnar1226 commented 4 years ago

I experienced the same issue. Solution I found by changing the order of migration files.

Imagine the case of posts and comments, we probably have to add the "foreign" on comments table with reference to post_id in posts table. In order to assign this foreign key on comments, posts table has to present first. ( on my case, I have resource and files. files has resource_id as foreign key )

On my case, I created migration file for comments first. After I changed the order, everything works fine. I just renamed the filed by interchanging the number in it.

image

Correct me if I am wrong.

I think this is my issue as well. old org mirgation with newer account migration. org table doesn't exist and the column types in org table is bigIncrement and the accounts foreign key is unsignedBigInteger but im getting the same error as OP for unable to add constraint.

agebreen commented 4 years ago

Usually it's bigInt vs int for me, but I just had a situation where I was trying to add foreign keys to tables that didn't exist yet, so changing the order that the migrations run fixed it.

For example, if you have a salmons and a goats table, and you trying to add a foreign key from the transactions table to the ID column in those tables, the migrations for salmons and goats must run first, otherwise you are trying to add foreign keys to tables that don't exist, which makes Laravel mad.

this is the solution

rassemdev commented 4 years ago

I have same problem in pivot table with Laravel-5-Generators-Extended.

I changed in pivot table:

$table->integer('item_id')->unsigned()->index();

to

$table->unsignedBigInteger('item_id')->index();

In Items table I have set:

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

This one worked for me

jianjye commented 4 years ago

If you are using MySQL, you must use unsignedBigInteger on your foreign key. This is because bigIncrements are created as unsigned big integer under the hood, and we need to match the column types.

For other databases, unsigned is not needed since it's not a supported type.

PQuelopana commented 4 years ago

Hola chicos, he resuelto esto cambiando toda la identificación de mi migración de bigIncrements a incrementos . Entonces, cada vez que genero una nueva migración, php artisan make:migration NAME --create=table_namesimplemente cambio los bigIncrements a incrementos para poder establecer una restricción FK.

agrega esto al campo bigInteger en la tabla que vas a relacionar ->unsigned()->nullable();, tenia el mismo problema y con esto lo resolvi.

DavidPrologo commented 4 years ago

I solve that create the migration in different order. Looks like the order of creation matter. laravel version 5.6.0. Perhaps it needs delete files and recreate, maybe.

osvaldodelr commented 4 years ago

Sorry for the poorly written English, this is the fault of the translator, I am Latin and I am still learning the English language. But already talking about the subject I have the same problem as everyone in Laravel 6.

The difference is that I have tried all the solutions proposed by you, but none works for me.

1) place the migrations in the correct order.

2) I put the attribute “bigIncrements and -> unsignedBigInteger” to both the main table and the dependent table.

3) apply the same Innodb engine to all my boards.

4) use the same utf8_general_ci convention in all my tables.

I really do not know what to do, I have tried all the proposals that you have made and none of them have worked. I need help !!! ...

Oluwafemi-Olayemi commented 4 years ago

This is coming late, what I did was just to change the date of when any migration that has foreign key included in it to a later time beyond the table it has referenced. Laravel's "php artisan migrate" creates migration with respect to the date as found in the filename. This, however, could have been fixed by just creating a new migration file and making your edition in that new file. bigIncrements and unsignedBigInterger / smallIncrement vs unsignedSmallInteger for the corresponding table argument in here also help in resolving my problem.

iurymacks2 commented 4 years ago

I was trying to create a foreign key in Laravel 6 (with artisan migrate), with primarykey (increments) and the another table unsigned Integer, don't worked and so I changed primarykey to bigIncrements and the fereignkey to bigInteger and works. I think don't works more to create foreignkey with (increments)/(unsigned)Integer but i'm not sure.

info (NOTES OF MIGRATION LARAVEL 5.8) Migrations & bigIncrements

As of Laravel 5.8, migration stubs use the bigIncrements method on ID columns by default. Previously, ID columns were created using the increments method.

This will not affect any existing code in your project; however, be aware that foreign key columns must be of the same type. Therefore, a column created using the increments method can not reference a column created using the bigIncrements method.

I hope it help someone!