Errors when refreshing migration of DB tables - mysql

After refreshing my migrations im getting issues between users migrations and account Types users table, cant figure out the problem.
Error
[Illuminate\Database\QueryException]
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'account_typ
es' already exists (SQL: create table `account_types` (`id` int unsigned no
t null auto_increment primary key, `name` varchar(50) not null, `created_at
` timestamp null, `updated_at` timestamp null) default character set utf8mb
4 collate utf8mb4_unicode_ci)
[PDOException]
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'account_typ
es' already exists
My Migrations
Account Types
public function up()
{
Schema::create('account_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 50);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('account_types');
}
Users
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('surname', 20);
$table->string('email')->unique();
$table->string('password');
$table->string('mobilephone', 9);
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
Relation ship between the users and account types, i believe that maybe the problem is here, but still cant figure out what is wrong with the migration code.
Relation of Users and Account Types
public function up()
{
Schema::table('users', function($table) {
$table->integer('account_type_id')->unsigned();
$table->foreign('account_type_id')
->references('id')->on('account_types');
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropForeign('users_account_type_id_foreign');
$table->dropColumn('account_type_id');
});
}

Like I had many times before there occurred an error when you were migrating and you get this error because the migration script hasn't had the chance to register the last migration.
If you don't care about the data already stored drop all the tables in your database manually (even the migrations table) and rerun.
When you have data in your tables you want to keep you should check this migrations table and look at the batch column. Put every entry on 1 you want to keep and set the row and the rows below it on 0 (maybe deleting them will also work). Run php artisan migrate. When using phpmyadmin you can update these rows by query, eg: UPDATE migrations SET batch=0 WHERE migration LIKE "%create_users_table";
Hope this helps :).

I think you should try this:
first remove account_types, users from migrations table in your database.
And refresh your migrations.
Hope this works for you!

Related

Even if i migrate:fresh it shows me that the table already exists.. why?

so i want to php artisan migrate:fresh but i get this error
Base table or view already exists: 1050 Table 'roles' already exists
even if i drop the database from phpmyadmin, clean the cache and create the database again it still show the same message the migration for the table rows is the following one:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolesTable extends Migration
{
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->tinyInteger('status');
});
}
public function down()
{
Schema::dropIfExists('roles');
}
}
the full error displayed:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'roles' already exists (SQL: create table roles (id bigint unsigned not null auto_increment primary key, name varchar(255) not null, guard_name varchar(255) not null, created_at timestamp null, updated_at timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')
Why is that? and what can or should I do?
First drop roles table using this code Schema::dropIfExists('roles'); then create.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolesTable extends Migration
{
public function up()
{
Schema::dropIfExists('roles'); //added
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->tinyInteger('status');
});
}
public function down()
{
Schema::dropIfExists('roles');
}
}
If it already exists before you did artisan migrate it will of course say this. Did you do migrate and it broke half way? You can reset it or just delete the table and try again (if you are in local dev and can delete it).
php artisan migrate:reset

Laravel Migration Error "Cannot add foreign key constraint" [duplicate]

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")
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.
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.
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.
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
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..
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');
}
}
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:
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');
});
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
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.
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.
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
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
if you get error change $table->id()(references) by $table->increments('id')
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
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
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

[Laravel 8.x][Eloquent] Copying rows to another table in mysql

I have a MySQL in the following format. I want to copy the entries in this table[products] to another table [user_products]. What is the best approach to do this?
In the user_products table while inserting the records, i will also have to add a user_id which gets passed to the code from a html form
You can use mysql trigger as explained here
Here is the migration.
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
....
});
Schema::create('user_products', function (Blueprint $table) {
$table->id();
....
});
\Illuminate\Support\Facades\DB::unprepared('
CREATE TRIGGER backup_users BEFORE INSERT ON `users` FOR EACH ROW
BEGIN
INSERT INTO user_products(id,other_columns)
values(new.id, new.other_columns);
END
');
}

Laravel migration "Cannot add foreign key constraint" error with MySQL database

I am developing a Laravel application. I am using MySQL for the database. I have created a model class and am trying to run the migration on it. But when, I run migration, I am getting error with adding the foreign key constraint. This is what I have done so far.
First I have migrated the built in Laravel user model running this command.
php artisan migrate
The users table was created in the database.
Then I created another model running this command.
php artisan make:model TodoItem -m
Then I added the following code to the migration file.
class CreateTodoItemsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('todo_items', function (Blueprint $table) {
$table->text('about');
$table->integer('user_id');
$table->increments('id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('todo_items');
}
}
AS you can see above, I am building the relationship between users table and todo_items table by adding a foreign key to the todo_items table. Then, I tried to migrate the TodoItem model by running this command.
php artisan migrate
When I run the command, I got this error.
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `todo_items` add constraint `todo_items_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
at /var/www/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")
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
2 PDOStatement::execute()
/var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
Please use the argument -v to see more details.
I did the same in my previous project which is using Postgresql. I was working fine. For this project, I am using MySQL database and now it is giving me the above error.
This is because you added $table->integer('user_id'); to your migration file. You must add an unsignedInteger instead of an integer, because the original id column of the users table is unsigned (and both columns must be exactly the same).
[EDIT]
Since Laravel 5.8, the id column type of the default users table is no longer an integer. It is now a bigInteger.
try
$table->unsignedBigInteger('user_id')->nullable()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Change this
$table->integer('user_id');
To this
$table->unsignedInteger('user_id')->nullable(false);
Try running it like this, this should work.
// also, do the unsigned thing the people above me posted
public function up()
{
Schema::create('todo_items', function (Blueprint $table) {
$table->text('about');
$table->integer('user_id');
$table->increments('id');
$table->timestamps();
});
Schema::table('todo_items', function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');
});
}
The issue was that either mysql didn't want foreign keys during table creation, or laravel was issuing them in the wrong order.
In short, this didn't work:
Schema::create('todo_items', function (Blueprint $table) {
$table->text('about');
$table->integer('user_id')->unsigned();
$table->increments('id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
This worked:
Schema::create('todo_items', function (Blueprint $table) {
$table->text('about');
$table->integer('user_id')->unsigned();
$table->increments('id');
$table->timestamps();
});
Schema::table('todo_items', function(Blueprint $table){
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

Migrations do not follow timestamp order

I am working with Laravel 5.4 trying to run my migrations. I have read that the order of execution follows the timestamps of the migration files. But this is not the case, as I receive the following error:
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
(SQL: alter table `aplicantes` add constraint `aplicantes_pais_id
_foreign` foreign key (`pais_id`) references `pais` (`id`))
These are my migrations files:
2014_01_01_100004_create_pais_table.php
2014_01_01_100005_create_departamentos_table.php
2014_01_01_100006_create_aplicantes_table.php
And this is where migration complains:
class CreateAplicantesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('aplicantes', function (Blueprint $table) {
$table->increments('id');
$table->string('nombre');
$table->unsignedInteger('pais_id');
$table->foreign('pais_id')->references('id')->on('pais');
$table->timestamps();
});
}
}
This is my Pais migration:
public function up()
{
Schema::create('pais', function (Blueprint $table) {
$table->increments('id');
$table->string('nombre');
$table->timestamps();
});
}
When I inspect the database, only the aplicantes table is created, which is the third in the order. I guess that is why the migration fails because the aplicantes table is being created first, which references a table that does not exist yet.
EDIT:
I have updated my migrations, creating an individual file for the foreign keys of every table. I'm getting an error when migrate:refresh, an access violation while dropping a foreign key, and I presume it's because of the same reason: migration is performing in alphabetical order, not by the timestamp.
UPDATE:
I had to rename every migrations file and now it seems working. Seems that migrate only care about days field in the naming convention of the migration files, not the seconds, as I was working with.
Despite that I see a correct order of migrate in migrations table, it complains of dropping foreign keys when I have my migration file like this:
class AddAplicantesForeignKey extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('aplicantes', function (Blueprint $table) {
$table->foreign('pais_id')->references('id')->on('pais')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('aplicantes', function(Blueprint $table)
{
$table->dropForeign('pais_id');
});
}
}
I manage to disable the complains by turn off the foreign key constraints check in my migration create table:
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::dropIfExists('aplicantes');
}
I am not happy with this solution, but it seems to only be working this way.