1

I have a music_upload table which references both album_id and user_id from both album and user table. The user_id foreign key works fine, it is the album_id foreign key which spews out this error

SQLSTATE[HY000]: General error: 1005 
Can't create table `nightingalev2`.`music_uploads` 
(errno: 150 "Foreign key constraint is incorrectly formed") 
(SQL: alter table `music_uploads` 
add constraint `music_uploads_album_id_foreign` foreign key (`album_id`) 
references `albums` (`id`) on delete cascade)

This is my album table schema

Schema::create('albums', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('artist_id');
            $table->string('name');
            $table->timestamps();

            $table->foreign('artist_id')->references('id')->on('artists');
        });

This is my music_uploads schema

Schema::create('music_uploads', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('album_id');
            $table->string('filename');
            $table->string('extension');
            $table->string('artistname')->nullable();
            $table->string('albumname')->nullable();
            $table->string('playtime')->nullable();
            $table->string('genres')->nullable();
            $table->integer('length')->nullable();
            $table->string('filesize')->nullable();
            $table->string('location')->nullable();
            $table->string('thumbnail')->nullable();
            $table->timestamps();

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

            $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
        });

And this is my users table schema if needed

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

I changed from $table->id() to $table->increment('id') and it didn't work. Changed the unsignedBitInteger into integer()->unsigned() and still didn't work.

philipxy
  • 14,867
  • 6
  • 39
  • 83
Sachin
  • 83
  • 8
  • The error seems to mention the `albums` table. Does that have a compatible data type for its `id` column? Signed integers and unsigned integers are not compatible for this purpose. – Bill Karwin Nov 11 '21 at 21:20
  • I didn't understand your question. Can you clarify in layman terms? – Sachin Nov 11 '21 at 21:26
  • Signed integers and unsigned integers are not compatible with respect to foreign key relationships. They must either both be signed or both be unsigned. But you seem to have made them both unsigned, according to the code you show above. The `id()` shortcut is equivalent to `bigIncrements('id')` which results in a `BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY` in MySQL parlance. Perhaps you created it with a different definition previously and the migration is using that? I'd go check in the MySQL client and use `SHOW CREATE TABLE ` for each table to confirm the data types. – Bill Karwin Nov 11 '21 at 21:40
  • I checked in `albums` table and in `id` column it says, `id bigint(20) unsigned NOT NULL AUTO_INCREMENT` – Sachin Nov 11 '21 at 21:56
  • Okay you can get a bit more detail on why MySQL thought it wasn't a proper foreign key by running the SQL statement `SHOW ENGINE INNODB STATUS\G`. The output is long, so you might want to use `tee status.txt` first to save it to a file. In the output, there should be a section for LAST FOREIGN KEY ERROR. – Bill Karwin Nov 11 '21 at 22:00
  • Here is the [link to the file] (https://ufile.io/sx1syjxw) – Sachin Nov 11 '21 at 22:08
  • I don't see a section for LAST FOREIGN KEY ERROR in that report. Either you restarted the daemon since you tried your migration, or you took the status from the wrong instance. – Bill Karwin Nov 11 '21 at 22:15
  • It's highly likely that the `music_uploads` migration is running **before** the `albums` migration. Can you share the names of these 2 migration files? – steven7mwesigwa Nov 11 '21 at 22:15
  • 1
    @steven7mwesigwa 2021_04_03_134426_create_music_uploads_table.php and 2021_11_11_195944_create_albums_table.php This one? – Sachin Nov 11 '21 at 22:21
  • @BillKarwin I think I commented out the portion that was throwing the error so it may not show in the report. – Sachin Nov 11 '21 at 22:22

1 Answers1

3

Your 2021_04_03_134426_create_music_uploads_table migration is essentially running before the 2021_11_11_195944_create_albums_table migration.

Solution.

STEP 1

Rename:
2021_04_03_134426_create_music_uploads_table
To:
2021_11_11_195944_create_music_uploads_table

STEP 2

Rename:
2021_11_11_195944_create_albums_table.php
To:
2021_04_03_134426_create_albums_table.php

STEP 3

Re-run the migration(s).

php artisan migrate

NOTES:

Always ensure that tables (migrations) with foreign key columns are created after the tables (migrations) they refer to.

In your case, you created the music_uploads migration on 03th/04/2021. And then created the albums migration on 11th/11/2021. Yet the albums migration had to be created earlier than that of music_uploads.

Migrations are run in the order of their prepended timestamp.

steven7mwesigwa
  • 5,701
  • 3
  • 20
  • 34