I have created two migrations:
Migration 1
Schema::create('responders', function (Blueprint $table) {
$table->increments('id');
$table->string('user_id');
$table->double('latitude', 10, 6);
$table->double('longitude', 10, 6);
$table->timestamps();
});
Migration 2
Schema::create('devices', function (Blueprint $table) {
$table->increments('id');
$table->string('user_id');
$table->string('device_id');
$table->string('device_token');
$table->timestamps();
$table->foreign('user_id')
->references('user_id')
->on('responders')
->onDelete('cascade');
});
When I start migration the error message is being thrown:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
(SQL: alter table devices add constraint devices_user_id_foreign
foreign key (user_id) references responders (user_id) on delete
cascade)
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
I specifically took care that the data types are the same. In this case both are of type string. Why does the foreign key can't be established?
A foreign key is a column (or columns) that references a column (most
often the primary key) of another table. The purpose of the foreign
key is to ensure referential integrity of the data. In other words,
only values that are supposed to appear in the database are permitted.
Here user_id in responders table isn't a key that's why it's showing this error.
Related
Schema::create('menus', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->integer('price');
$table->text('description');
$table->timestamps();
});
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->timestamps();
});
Schema::create('category_menu', function (Blueprint $table) {
$table->increments('id');
$table->integer('menu_id')->unsigned()->nullable();
$table->foreign('menu_id')->references('id')
->on('menus')->onDelete('cascade');
$table->integer('category_id')->unsigned()->nullable();
$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
$table->timestamps();
});
When I run php artisan:migrate, I get the following error.
SQLSTATE[HY000]: General error: 1005 Can't create table `mieaceh`.`category_menu` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `category_menu` add constraint `category_menu_menu_id_foreign` foreign key (`menu_id`) references `menus` (`id`) on delete cascade)
This is due to mismatch of datatype of foreign key column and the referenced column most likely
When you create a primary key with $table->id() the datatype of the auto incrementing id column is unsignedBigInteger so you must have foreign key also with the same datatype
Schema::create('category_menu', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('menu_id');
$table->foreign('menu_id')->references('id')
->on('menus')->onDelete('cascade');
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
$table->timestamps();
});
You shouldn't make the columns in a pivot table nullable for the foreign keys to maintain data integrity.
Also be consistent with the datatype for primary key columns as well as definitions - when using $table->id() keep that consistent across all migrations for all tables. That way you will have less chances of mismatch when defining foreign keys as $table->unsignedBigInteger()
laravel migrations files contains a datetime slug that determine which file will be migrated first
notice the order
2021_10_11_101533_create_posts_table.php
2014_10_12_000000_create_users_table.php
when you run
php artisan migrate
posts table will be migrated first and it contains a foriegn key
user_id
which references a primary key on users table
id
but the users table doesn't exists yet, to fix this issues change the files names and make sure users table migrate first like this
notice the order
2014_10_10_000000_create_users_table.php
2021_10_11_101533_create_posts_table.php
short pattern for declaring a foreign key
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
Try to create foreign key in Laravel 7 but when I migrate tables using artisan it gives error
SQLSTATE[HY000]: General error: 3780 Referencing column 'remote_id' and referenced column 'parent_id' in foreign key constraint 'products_remote_id_foreign' are incompatible. (SQL: alter table products add constraint products_remote_id_foreign foreign key (remote_id) references categories (parent_id) on delete cascade)
My categories table
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('parent_id');
$table->tinyInteger('depth');
$table->string('name');
$table->string('slug');
$table->text('description');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
});
My products table
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('remote_id');
$table->foreign('remote_id')->references('parent_id')->on('categories')->onDelete('cascade');
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->string('name');
$table->text('description');
$table->integer('price');
$table->tinyInteger('status')->default(1);
$table->integer('qty');
$table->string('barcode')->nullable();
$table->string('image');
$table->text('images')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
});
Any ideas as to what I've done wrong?
Thanks for help!!!
As mentioned by aynber, for foreign keys to be compatible, they must be of the same type. Your remote_id in your products table is an unsignedBigInteger while the key you are trying to reference in your categories table, parent_id, is an integer. To fix this either change category_id in your products table to an integer or change parent_id in your categories table to an unsignedBigInteger.
Edit:
I looked a little more into foreign keys and found this useful answer on another post. Foreign keys need to have a unique constraint or be a primary key. Since your remote_id column is referencing parent_id which is neither a primary key nor has a unique constraint, you are getting this error.
The solution given in the other question for adding a unique constraint is running this command(modified for your tables):
alter table categories add constraint uq1 unique (parent_id);
Using Laravel 5.3 and Eloquent model, Trying to make a user role model.
the main schema that I have 2 tables users and roles, each user have a role and every role have many users (one to many relationship).
when i'm trying to make a foreign key in user table that references the id in roles table it gives me this error
In Connection.php line 647:
SQLSTATE[HY000]: General error: 1005 Can't create table
mydata.#sql-7e0_71 (errno: 150 "Foreign key constraint is incorrectly
formed") (SQL: alter table "user" add constraint
"user_role_id_foreign" foreign key ("role_id") references roles("id"))
In Connection.php line 449:
SQLSTATE[HY000]: General error: 1005 Can't create table
mydata.#sql-7e0_71 (errno: 150 " Foreign key constraint is
incorrectly formed")
Note: I'm using artisan command migrate, and I've tried these answers 1,2
here is my up() function for my user migration
public function up()
{
Schema::create('user', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->integer('role_id')->unsigned();
$table->string('remember_token')->nullable();
$table->timestamps();
$table->foreign('role_id')->references('id')->on('role');
});
}
and for role table
public function up()
{
Schema::create('role', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
}
You are trying to add a foreign key that have a reference on the roles table (->on('roles')), but in your migration file you are creating a table named role (Schema::create('role', ...).
You need to match those.
Either changed the name of the role table to roles or your reference to the role table.
Below are my migrations
The users table have a relation with the customer table
In user:
$table->integer('customer_id')->unsigned();
$table->foreign('customer_id')->references('id')->on('customers');
When i call php artisan migrate:refresh --seed, artisan given me the following error:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `users` add constraint `users_customer_id_foreign` foreign ke
y (`customer_id`) references `customers` (`id`))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
Because the customers table does not exists... (obvious)
Is there a way to solve this problem? I know changing the date of the files will fix this but there should be a beter approach
You have to create the table you're referencing to before adding the foreign key. A solution would be to remove the foreign key constraint from your user table migration and create a new migration which adds the foreign key constraints.
Try to make it separately.
public function up()
{
Schema::create('users', function(Blueprint $table) {
$table->increments('id');
$table->integer('costumer_id')->unsigned();
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function($table) {
$table->foreign('costumer_id')->references('id')->on('costumers');
});
}
Another thing you can try(since laravel 5.3):
unsignedInteger('column_name') instead of ('column_name')-unsigned()
If you had set one field as "Unsigned" and other one not. Once you should set both columns to Unsigned it works.
When I'm trying to set a foreign key constraint in laravel 5 with migrations I receive the error:
[Illuminate\Database\QueryException] SQLSTATE[HY000]: General
error: 1215
Cannot add foreign key constraint (SQL: alter table
rittenregistratie add co nstraint
rittenregistratie_karakterrit_id_foreign foreign key
(karakterrit_id) references karakterrit (id) on delete
cascade) [PDOException] SQLSTATE[HY000]: General error: 1215
Cannot add foreign key constraint D:\wamp\www>
But I have now idea why??? The order of migrating is right so why do I receive this error? The table rittenregistratie has a foreign key called karakterrit_id this is the primary key in the table karakterrit.
This is my migration rittenregistratie:
public function up()
{
Schema::create('rittenregistratie', function (Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->timestamps('datum');
$table->integer('beginstand');
$table->integer('eindstand');
$table->text('van');
$table->text('naar');
$table->text('bezoekadres');
$table->text('geredenroute');
$table->integer('karakterrit_id')->default(1);
$table->text('toelichting');
$table->integer('kilometerszakelijk');
$table->integer('kilomteresprive');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('karakterrit_id')
->references('id')
->on('karakterrit')
->onDelete('cascade');
});
}
Add
$table->integer('karakterrit_id')->unsigned()->default(1);
Have you created the users Table and karakterrit that you used in your query. If you have both tables, check the creation date of the migration files they both should be created before other table that references them.
Another problem might be MyISAM which does not support. Instead use InnoDB
DB::statement('ALTER TABLE categories ENGINE = InnoDB');
One common problem with even Laravel 8 is that the table on which the foreign_id is being set up is created earlier. So when migrations run, they run in order and can't find foreign id referenced table. If you see that happen to change the name of the second table to an earlier date and you are sorted.
So say rename 2020_12_04_081855_create_developers_table.php to 2020_12_03_081855_create_developers_table.php.
That will take care of it. Remember the date should be earlier than the first table.
for the most of the case the referenced column must be either primary key or have unique key from my findings
Laravel 8: I renamed my two migration files with the foreign key constraints to the latest date. This solved for me.