I'm having a problem with migration on my Laravel project.
Since i'm fairly new to Laravel I can't figure it out.
I want to add a foreign key to an already existing table and this works, but when I refresh my migrations I get this error:
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key
constraint fails (SQL: drop table `battles`)
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key
constraint fails
These are the migrations I currently have:
Table Projects
class CreateProjectsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('body');
$table->string('tags');
$table->string('img');
$table->string('img_tricolor');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('projects');
}
}
Table Battles
class CreateBattlesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('battles', function (Blueprint $table) {
$table->increments('id');
$table->string('battle_theme');
$table->boolean('battle_active');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('battles');
}
}
Adding foreign key for battles in projects
class AddProjectsBattleIdFk extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('projects', function (Blueprint $table) {
$table->integer('battle_id')->unsigned();
$table->foreign('battle_id')->references('id')->on('battles')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('projects', function (Blueprint $table) {
//
});
}
}
I suppose it has something to do with the battles table.
In down methods you need to remove foreign keys first:
In CreateProjectsTable
public function down()
{
Schema::table('projects', function (Blueprint $table) {
$table->dropForeign('projects_user_id_foreign');
});
Schema::drop('projects');
}
In AddProjectsBattleIdFk
public function down()
{
Schema::table('projects', function (Blueprint $table) {
$table->dropForeign('projects_battle_id_foreign');
$table->dropColumn('battle_id');
});
}
I had the same problem,the Marcin's answer worked but I also found that another option is using fresh instead of refresh, in that case you don't need to remove foreign keys.
I don't know if this is more updated solution will help someone that is facing the same problem:
use this in your migration down function
Schema::disableForeignKeyConstraints();
I usually create as the last migration or name it to be sorted as last (cause migration comand runs the files under migration folder by order) something like 2099_12_32_AlterTablesCreateForeignKeysmigration where in the up function I specify all my keys for every table and at the end enable foreign keys constraints Schema::enableForeignKeyConstraints(); and then then in the down i just disabled them Schema::disableForeignKeyConstraints(); to allow the reset to truncate the tables.
Related
Syntax error or access violation: 1072 Key column 'collection_id' doesn't exist in table (SQL: alter table products add constraint products_collection_id_foreign foreign key (collection_id) references collections (id) on delete cascade)
So im having this issue trying to relation products with collections with a collection_id.
This is my collection migration
class CreateCollectionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('collections', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('author');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('collections');
}
}
This is my product migration
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->integer('price');
$table->string('src');
$table->unsignedBigInteger('collection_id');
$table->foreign('collection_id')->references('id')->on('collections')->onDelete("cascade");
$table->integer('amount');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
You can do it the following way.
$table->unsignedBigInteger('collection_id');
$table->foreign('collection_id')->references('id')->on('collections')->onDelete("cascade");
And one more thing run the following command :
php artisan migrate:fresh
or
php artisan migrate:refresh
hope your problem will be resolved.or
can follow the following URL
Laravel migration: "Foreign key constraint is incorrectly formed" (errno 150)
are your migrations running correctly you might also check the migrations sequence on creating the table if the collection is being created first before the products, if products are created before collection it throws this error because the collection is not yet created, also there's a shortcut for defining foreign keys which is
$table->foreignId('collection_id')->constrained()->cascadeOnDelete();
In my laravel appication I have two migrations.
2022_06_08_075452_create_schedule_types_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateScheduleTypesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('schedule_types', function (Blueprint $table) {
$table->increments('id');
$table->string('schedule_type_name');
$table->string('schedule_type_color');
$table->string('schedule_type_description');
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('schedule_types');
}
}
2022_06_08_054916_create_schedules_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSchedulesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('schedules', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('department_id');
$table->foreign('department_id')->references('id')->on('departments');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedBigInteger('company_id');
$table->foreign('company_id')->references('id')->on('companies');
$table->unsignedBigInteger('added_by');
$table->foreign('added_by')->references('id')->on('users');
$table->string('schedule_name');
$table->integer('schedule_type_id');
$table->foreign('schedule_type_id')->references('id')->on('schedule_types');
$table->date('schedule_start_date')->nullable();
$table->date('schedule_end_date')->nullable();
$table->date('schedule_actual_end_date')->nullable();
$table->time('schedule_travel_time')->nullable();
$table->unsignedBigInteger('rotation_scheme_id');
$table->foreign('rotation_scheme_id')->references('id')->on('schedule_rotational');
$table->date('rotational_schedule_period_from')->nullable();
$table->date('rotational_schedule_period_to')->nullable();
$table->unsignedBigInteger('rotation_shift_id');
$table->foreign('rotation_shift_id')->references('id')->on('schedule_has_shift');
$table->timestamps();
$table->softDeletes();
$table->index([
'department_id', 'user_id', 'schedule_type_id', 'company_id', 'added_by','schedule_start_date',
'schedule_end_date', 'rotation_scheme_id', 'rotational_schedule_period_from', 'rotational_schedule_period_to',
'rotation_shift_id']);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('schedules');
}
}
But, wen I tried to run my migrations, I'm getting following error,
SQLSTATE[HY000]: General error: 1005 Can't create table
hrapp_dev.schedules (errno: 150 "Foreign key constraint is
incorrectly formed") (SQL: alter table schedules add constraint
schedules_schedule_type_id_foreign foreign key (schedule_type_id)
references schedule_types (id))
I initially thought this is occurring due to an int and bigint issue, but both are in int....
UPDATE
I ran the two migration files one at a time due to timestamp issue, but still getting the same issue...
Your foreign key schedule_type_id should be unsigned for the relationship to work. In your 2022_06_08_054916_create_schedules_table.php change to:
$table->integer('schedule_type_id')->unsigned();
Do it this way following the more cleaner syntax from Laravel 7.x:
class CreateSchedulesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('schedules', function (Blueprint $table) {
$table->bigIncrements('id');
$table->foreignId('department_id')->constrained();
$table->foreignId('user_id')->constrained();
$table->foreignId('company_id')->constrained();
$table->foreignOd('added_by')->constrained('users');
$table->string('schedule_name');
// Here is your problem the schedule_type_id was not correctly formed
$table->foreignId('schedule_type_id')->constrained();
$table->date('schedule_start_date')->nullable();
$table->date('schedule_end_date')->nullable();
$table->date('schedule_actual_end_date')->nullable();
$table->time('schedule_travel_time')->nullable();
$table->foreignId('rotation_scheme_id')->constrained('schedule_rotational');
$table->date('rotational_schedule_period_from')->nullable();
$table->date('rotational_schedule_period_to')->nullable();
$table->foreignId('rotation_shift_id')->constrained('schedule_has_shift');
$table->timestamps();
$table->softDeletes();
$table->index([
'department_id', 'user_id', 'schedule_type_id', 'company_id', 'added_by','schedule_start_date',
'schedule_end_date', 'rotation_scheme_id', 'rotational_schedule_period_from', 'rotational_schedule_period_to',
'rotation_shift_id']);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('schedules');
}
}
the foreignId('tablename_id`) creates a foreign key and constrained() will make it constrained using the column name to determine the table. If you have a different table name than the one used in column name then you can pass the table in constrained('table')
when i tried delete item in laravel i get this message
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (larblog.comments, CONSTRAINT comments_article_id_foreign FOREIGN KEY (article_id) REFERENCES articles (id)) (SQL: delete from articles where id = 2)
this my delete function
public function DeleteArticle($id){
$article = Article::find($id);
$article->delete();
return redirect("article");
}
this create articles table code
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateArticle extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('articles');
}
}
and this create comments table code
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateComments extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->text('comment');
$table->timestamps();
$table->integer('article_id')->unsigned();
$table->foreign('article_id')->references('id')->on('articles');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
}
Iam tried to use this solution but did not work
$table->foreign('article_id')->references('id')->on('articles')->onUpdate('cascade')-
>onDelete('cascade');
as you know your comments depends on articles once a article is delete then comment's relation going to break so either you first delete all comment's of that artical or set foreign key null to all the comment for that article
so that why you need to update your mygration with
$table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');
or
$table->integer('article_id')->unsigned()->nullable();
$table->foreign('article_id')->references('id')->on('articles')->onDelete('set null');
I'm trying to create a migration on Laravel 8, Here's my table
class CreateProductVariationOrderTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product_variation_order', function (Blueprint $table) {
$table->integer('order_id')->unsigned()->index();
$table->integer('product_variation_id')->unsigned()->index();
$table->integer('quantity')->unsigned();
$table->timestamps();
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->foreign('product_variation_id')->references('id')->on('product_variations')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('product_variation_order');
}
}
And When I run php artisan migrate I get this chunk of error : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table product_variation_orderadd constraintproduct_variation_order_order_id_foreign foreign key (order_id) references orders (id) on delete cascade)
⚠️ EDIT: Here's my product_variation migration file.
class CreateProductVariationsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product_variations', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned()->index();
$table->string('name');
$table->integer('price')->nullable();
$table->integer('order')->nullable();
$table->timestamps();
$table->foreign('product_id')->references('id')->on('products');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('product_variations');
}
}
The foreign key has to be the same type as the reference key.
In your orders table, you define id as bigIncrements() which is unsigned big integer.
In your product_variation_order table, you define order_id as unsigned integer.
So the two keys do not match. Generally you should use big integer because it allows your database to grow larger and space difference between integer and big integer isn't significant.
So change order_id as unsigned big integer.
$table->unsignedBigInteger('order_id')->nullable();
Also for consistency, all keys should be bigIncrements() or unsignedBigInteger(), this will save you headache in the future.
Use this code:
product_variations:
class CreateProductVariationsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product_variations', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('product_id')->unsigned()->nullable();
$table->string('name');
$table->integer('price')->nullable();
$table->integer('order')->nullable();
$table->timestamps();
$table->foreign('product_id')->references('id')->on('products');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('product_variations');
}
}
product_variation_order:
class CreateProductVariationOrderTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('product_variation_order', function (Blueprint $table) {
$table->bigInteger('order_id')->unsigned()->nullable();
$table->bigInteger('product_variation_id')->unsigned()->nullable();
$table->integer('quantity')->unsigned();
$table->timestamps();
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->foreign('product_variation_id')->references('id')->on('product_variations')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('product_variation_order');
}
}
Sometimes it is necessary to migrate first the table in which there is the primary key before the table which contains the foreign key. To migrate a specific table use :
php artisan migrate --path=/database/migrations/file_migration_name.php
Issue
I'm making a login app with laravel , i want to make the role for users but i came accross this error
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1005 Can't create table `accounting`.`role_user`
(errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `role_user` add constraint `role_user_role_id_foreign` foreign key (`role_id`) references `roles` (`id`))
Code
This is the code which causes mentioned error:
CreateUsersTable
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
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();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
CreateRolesTable
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
}
CreateRoleUser
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateRoleUser extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->integer('role_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles')->cascade('delete');
$table->foreign('user_id')->references('id')->on('users')->cascade('delete');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
Any ideas how to fix this issue?
Make sure the data type matches in both cases. Your primary key data types and foreign key data type must be the same.
Secondly, make sure you put the migration file sequentially. Let's say you have three tables roles, users, and role_user. You want to build a relation between roles with role_user and users with role_user. In the migration directory, the roles and users table(migration file) should come first, then the role_user table(migration file) as the role_user table holds a reference to those two tables. The sequence is maintained by the time of the file created. So you can rename the file changing the time (which is in year_month_date_seconds) format so that it stands before the role_user table. Or you may create a directory for them. Then migrate them separately.
Not helping much, but still shouldn't this be
$table->foreign('role_id')->references('id')->on('roles')->cascade('delete');
$table->foreign('user_id')->references('id')->on('users')->cascade('delete');
replace by
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');