Foreign key add constraint error in laravel migration - mysql

I have written the migration in laravel but when I run this migration I received following error
> SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
> (SQL: alter table `campaign_notifications` add constraint `campaign
> _notifications_campaign_id_foreign` foreign key (`campaign_id`) references `campaigns` (`id`) on delete cascade)
My migration code
Schema::create('campaign_notifications', function (Blueprint $table) {
$table->increments('id');
$table->integer('campaign_id')->index();
$table->string('user_uuid')->nullable();
$table->string('post_id')->default(0);
$table->tinyInteger('is_opened')->default(0);
$table->tinyInteger('sent')->default(0);
$table->string('payload')->nullable();
$table->string('failed_type')->nullable();
$table->timestamps();
$table->foreign('campaign_id')->references('id')->on('campaigns')->onDelete('cascade');
});

First make sure you already have a campaign table in your DB (Take a look in the timestamps of your migrations), so that you can reference the table in your current migration. Basically for this migration to work you need a campaign table in your database, you can't run the campaign table migration after this one.
Also, change your campaign_id to unsigned integer
$table->unsignedInteger('campaign_id');
$table->foreign('campaign_id')->references('id')->on('campaigns')->onDelete('cascade');

Your migration code will look like :
Schema::create('campaign_notifications', function (Blueprint $table) {
$table->increments('id');
$table->string('user_uuid')->nullable();
$table->string('post_id')->default(0);
$table->tinyInteger('is_opened')->default(0);
$table->tinyInteger('sent')->default(0);
$table->string('payload')->nullable();
$table->string('failed_type')->nullable();
$table->bigInteger('campaign_id')->unsigned();
$table->foreign('campaign_id')->references('id')->on('campaigns')->onDelete('cascade');
$table->index('campaign_id');
$table->timestamps();
});

Related

Migration for self referencing many to many relation failing in Laravel with "Foreign key constraint is incorrectly formed"

I try to implement a self referencing many to many relationship. So a product can have one or more alternative products. When I run the migration I get this error:
SQLSTATE[HY000]: General error: 1005 Can't create table xxx.productalternatives (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table productalternatives add constraint productalternatives_original_product_id_foreign foreign key (original_product_id) references products (id))
And thats how my migration looks like:
Schema::create('productalternatives', function (Blueprint $table) {
$table->unsignedBigInteger('original_product_id');
$table->unsignedBigInteger('alternate_product_id'); $table->timestamps();
$table->foreign('original_product_id')->references('id')->on('products');
$table->foreign('alternate_product_id')->references('id')->on('products');
});
Any ideas whats the reason for that?
Based on my experience, when you are working with a table that needs a self-referencing foreign key, you have to first create the table and then (in a new "query") add the foreign key:
Schema::create('productalternatives', function (Blueprint $table) {
$table->unsignedBigInteger('original_product_id');
$table->unsignedBigInteger('alternate_product_id');
$table->timestamps();
});
Schema::table('productalternatives', function (Blueprint $table) {
$table->foreign('original_product_id')->references('id')->on('products');
$table->foreign('alternate_product_id')->references('id')->on('products');
});

Unable to rename a foreign column in laravel 5.8 - column not found error

I am trying to rename a foreign column. So I write the following code:
Schema::table('floor_plans', function (Blueprint $table) {
$table->dropForeign(['unit_type_id']);
$table->renameColumn('unit_type_id', 'utd_id');
$table->foreign('utd_id')
->references('id')
->on('unit_type_details')
->onDelete('cascade');
});
But it throws
Doctrine\DBAL\Schema\SchemaException : There is no column with name 'unit_type_id ' on table 'floor_plans'.
at D:\wamp64\www\amenity\vendor\doctrine\dbal\lib\Doctrine\DBAL\Schema\SchemaException.php:85
81| * #return \Doctrine\DBAL\Schema\SchemaException
82| */
83| public static function columnDoesNotExist($columnName, $table)
84| {
> 85| return new self(
86| sprintf("There is no column with name '%s' on table '%s'.", $columnName, $table),
87| self::COLUMN_DOESNT_EXIST
88| );
89| }
Then I tried by turning foreign checks off:
DB::statement('SET FOREIGN_KEY_CHECKS=0');
$table->dropForeign(['unit_type_id']);
$table->renameColumn('unit_type_id ', 'utd_id');
DB::statement('SET FOREIGN_KEY_CHECKS=1');
But same error, the column not found.
Then I tried to drop foreign with exact ForeignKeyConstraint as :
DB::statement('SET FOREIGN_KEY_CHECKS=0');
$table->dropForeign('floor_plans_unit_type_id_foreign');
$table->renameColumn('unit_type_id', 'utd_id');
DB::statement('SET FOREIGN_KEY_CHECKS=1');
$table->foreign('utd_id')
->references('id')
->on('unit_type_details')
->onDelete('cascade');
Still the same error.
I then even tried with Raw SQL as:
DB::statement("ALTER TABLE floor_plans
DROP FOREIGN KEY `floor_plans_unit_type_id_foreign`,
ADD CONSTRAINT `floor_plans_unit_type_detail_id_foreign` FOREIGN KEY (`unit_type_detail_id`) REFERENCES `unit_type_details` (`id`)");
And this gives me the following error:
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'floor_plans_unit_type_id_foreign'; check that column/key exists (SQL: ALTER TABLE floor_plans
DROP FOREIGN KEY `floor_plans_unit_type_id_foreign`,
ADD CONSTRAINT `floor_plans_unit_type_detail_id_foreign` FOREIGN KEY (`unit_type_detail_id`) REFERENCES `unit_type_details` (`id`))
And here is the screenshot of the table.
All I want is to rename unit_type_id to unit_type_detail_id.
#PS: the table is not empty. And, I am happy to run even if you provide me the raw MySQL query.
Their is an additional space on unit_type_id.
Schema::table('floor_plans', function (Blueprint $table) {
$table->dropForeign(['unit_type_id']);//note foreign key already dropped so also you have to make this line also as comment when you test.
//$table->renameColumn('unit_type_id ', 'utd_id');//remove this space and try again
$table->renameColumn('unit_type_id', 'utd_id');//after remove space
$table->foreign('utd_id')
->references('id')
->on('unit_type_details')
->onDelete('cascade');
});

I need to update existing foreign key, but I can't drop it in order to update it

I've got a migration to correct existing foreign key, it looks like this
public function up()
{
Schema::table('content_term', function (Blueprint $table) {
$table->dropForeign('content_term_content_id_foreign');
$table->foreign('content_id')->references('id')->on('content')->onUpdate('cascade')->onDelete('cascade');
});
}
The original table and foregin key looked like this
public function up()
{
Schema::create('content_term', function (Blueprint $table) {
$table->increments('id');
$table->unsignedBigInteger('content_id')->unsigned();
$table->unsignedInteger('term_id');
$table->foreign('content_id')->references('id')->on('content')->onUpdate('cascade');
$table->foreign('term_id')->references('id')->on('terms')->onDelete('cascade')->onUpdate('cascade');
});
}
I forgot to add onDelete('cascade') for content_id foreign key creation and need to correct that in a new migration.
When I run php artisan migrate with thew latest migration I've added I get this
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'content_term_content_id_foreign'; check that column/key exists (SQL: alter table content_term drop foreign key content_term_content_id_foreign)
MYSQL complains that the foreign key does not exist in content_term table. When I check that table using phpmyadmin I can clearly see that key exists. See attached pic for proof of that.
What's the problem with my new migration, why is this line causing a problem:
$table->dropForeign('content_term_content_id_foreign');

Laravel Migration Error on foreign key constraint

I have a problem running the migration of my Laravel project. When I run artisan migrate, it stops in the foreign key. Can someone help me with this? I tried the solution on the other similar questions but it does not work.
Error Message: SQLSTATE[HY000]: General error: 1005 Can't create table.
airways.#sql-4588_cfb (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table flights add constraint flights_airport_departure_foreign
foreign key (airport_departure) references airports (airport_code) on delete cascade)
flights_table.php
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->integer('flight_number')->primary();
$table->string('airline');
$table->integer('airport_departure')->unsigned();
$table->string('departure_time');
$table->integer('airport_arrival')->unsigned();
$table->string('arrival_time');
$table->string('flight_duration');
$table->timestamps();
});
Schema::table('flights', function($table) {
$table->foreign('airport_departure')
->references('airport_code')->on('airports')
->onDelete('cascade');
$table->foreign('airport_arrival')
->references('airport_code')->on('airports')
->onDelete('cascade');
});
}
airports_table.php
public function up()
{
Schema::create('airports', function (Blueprint $table) {
$table->integer('airport_code')->primary();
$table->string('airport_name');
$table->string('airport_location');
$table->string('airport_state');
$table->timestamps();
});
}
Your foreign key column types are wrong. You're not setting the airport_code as an unsigned integer but airport_departure and airport_arrival are expecting unsigned integers. Also you'll need to create the airports table before creating flights table, not the other way 'round as suggested by others.
Rollback your migration, change the order of migration i.e if the airport table is 2014_10_12_0000 and the flights_table is 2014_10_12_00001, change airport table to 0002.

laravel migration error while adding 2 foreign key

I am using Laravel migrations to create my MySQL database, and have two tables papers and answers, and need to connect both tables using foreign keys. I have the paper_id as well as question_no as the foreign keys. but when adding foreign key I get an error.
My migration for paper table and answer table
Schema::create('exampapers', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('paper_id');
$table->integer('question_no');
$table->text('question');
$table->string('answer1');
$table->string('answer2');
$table->string('answer3');
$table->string('answer4');
$table->integer('answerC');
$table->string('knowarea');
$table->timestamps();
$table->index(['paper_id','question_no']);
});
Schema::create('answers', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('paper')->unsigned();
$table->integer('question')->unsigned();
$table->integer('answers');
$table->timestamps();
});
and this is my code for creating foreign keys,
Schema::table('answers',function($table){
$table->foreign('paper')->references('paper_id')->on('exampapers');
$table->foreign('question')->references('question_no')->on('exampapers');
});
The error I get through php artisan is,
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error:
1005
Can't create table exam_paper.#sql-b88_630 (errno: 150 "Foreign key
constraint is incorrectly formed") (SQL: alter table answers add
constraint answers_paper_foreign
foreign key (paper) references exampapers (paper_id))
I referred most of the other posts and already tried unsignedInteger() data type, running the table creation before foreign key creation.
What am I doing wrong in my code?
You need to add ->unsigned()->nullable()->index(); in both column (i.e. in paper_id and in question in exampapers table).
Try to add like below in exampapers table:
$table->integer('paper_id')->unsigned()->nullable()->index();
$table->integer('question_no')->unsigned()->nullable()->index();
Now run php artisan migrate and problem fixed!
Hope this helps you!
You need to make the key in the exampapers table unsigned too:
$table->integer('paper_id')->unsigned();
Or:
$table->insignedInteger('paper_id');
Or remove the unsigned() method from the foreign key definition:
$table->integer('paper');
I have made some edits to your migration code. Hope this will work
Schema::create('exampapers', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('paper_id')->unsigned()->index();
$table->integer('question_no')->unsigned()->index();
$table->text('question');
$table->string('answer1');
$table->string('answer2');
$table->string('answer3');
$table->string('answer4');
$table->integer('answerC');
$table->string('knowarea');
$table->timestamps();
//$table->index(['paper_id','question_no']);
});
Schema::create('answers', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('paper')->unsigned()->index();
$table->integer('question')->unsigned()->index();
$table->integer('answers');
$table->timestamps();
});
Schema::table('answers',function($table){
$table->foreign('paper')->references('paper_id')->on('exampapers');
$table->foreign('question')->references('question_no')->on('exampapers');
});