9
votes

PHP Laravel PDOException La colonne de référence d'erreur générale et la colonne référencée dans une contrainte de clé étrangère sont incompatibles

Je fais actuellement des migrations dans Laravel via le Terminal, et j'ai ces deux erreurs lorsque j'essaie d'utiliser php artisan migrate; J'imprimerai les erreurs ci-dessous:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateContactsTable extends Migration
{
    public function up()
    {
        Schema::create('contacts', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user1_id');
            $table->unsignedInteger('user2_id');
            $table->integer('room_id')->unique();
            $table->timestamps();
            $table->foreign('room_id')->references('id')->on('rooms');
            $table->foreign('user1_id')->references('id')->on('users');
            $table->foreign('user2_id')->references('id')->on('users');
        });
    }

    public function down()
    {
        Schema::dropIfExists('contacts');
    }
}

D'après le code contenu dans le suivi des exceptions, le problème semble être dans le code ci-dessous:

Exception trace:

  1   PDOException::("SQLSTATE[HY000]: General error: 3780 Referencing column 'room_id' and referenced column 'id' in foreign key constraint 'contacts_room_id_foreign' are incompatible.")
      /Users/shaquilenoor/Desktop/chatapi/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /Users/shaquilenoor/Desktop/chatapi/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

des idées sur la façon dont je peux résoudre?


0 commentaires

9 Réponses :


0
votes

Dans ce cas, room_id doit être non signé. Essayez ceci:

 public function up()
    {
        Schema::create('contacts', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user1_id');
            $table->unsignedInteger('user2_id');
            $table->integer('room_id')->unique()->unsigned();
            $table->timestamps();
            $table->foreign('room_id')->references('id')->on('rooms');
            $table->foreign('user1_id')->references('id')->on('users');
            $table->foreign('user2_id')->references('id')->on('users');
        });
    }


0 commentaires

-1
votes

Cela est dû au fait que les clés étrangères ont été définies avant la création de la table rooms. vous pouvez résoudre ce problème en procédant comme suit.

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateContactsTable extends Migration
{
    public function up()
    {
        Schema::disableForeignKeyConstraints();
        Schema::create('contacts', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user1_id');
            $table->unsignedInteger('user2_id');
            $table->integer('room_id')->unique();
            $table->timestamps();
            $table->integer('room_id')->unsigned();
            $table->integer('user1_id')->unsigned();
            $table->integer('user2_id')->unsigned();
            $table->foreign('room_id')->references('id')->on('rooms');
            $table->foreign('user1_id')->references('id')->on('users');
            $table->foreign('user2_id')->references('id')->on('users');
        });
        Schema::enableForeignKeyConstraints();
    }

    public function down()
    {
        Schema::disableForeignKeyConstraints();
        Schema::dropIfExists('contacts');
        Schema::enableForeignKeyConstraints();
    }
}


0 commentaires

28
votes

Si vous êtes sur Laravel 5.8 , la nouvelle migration a été modifiée en gros incréments. Par conséquent, pour corriger l'erreur de réfraction, remplacez simplement entier par bigInteger , pour exemple:

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

Deviendra:

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


0 commentaires

5
votes

Soit modifier la migration d'origine de

bigIncrements ()

à seulement

incréments ();


Ou Dans votre colonne de clé étrangère, faites

bigInteger ()

au lieu de

entier ()


1 commentaires

Veuillez ajouter quelques explications à votre réponse afin que d'autres puissent en tirer des leçons - pourquoi est-ce nécessaire?



3
votes

Dans Laravel 6.0 , les migrations sont identiques à celles mentionnées dans @Payam Khaninejad . ie

$table->bigInteger('user_id')->unsigned()->index();

Je mets à jour cela pour Laravel 6.0 parce que je suivais un ancien tutoriel qui a montré la même erreur. p>


0 commentaires

0
votes

Également dans laravel 7.x, vous devrez peut-être changer:

$table->increments('id'); // UNSIGNED INTEGER
// to 
$table->id(); // UNSIGNED BIGINT


1 commentaires

Veuillez ajouter une explication à votre réponse afin que d'autres puissent en tirer des leçons - comment ce changement est-il lié au message d'erreur donné?



0
votes

Il semble que ce soit un problème avec les tables qui ont été migrées dans les anciennes versions. J'ai eu le même problème et dans mon cas, j'ai utilisé deux types de déclaration différents pour chaque clé étrangère. "integer" et "unsignedInteger"

        $table->integer('webcam_id');
        $table->unsignedInteger('user_id');
     

        $table->foreign('webcam_id')
            ->references('id')
            ->on('webcam');

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


0 commentaires

1
votes

table des utilisateurs
$table->integer('user_id')->unsigned();  //adding unsigned() here, will fix the error
$table->foreign('user_id')->references('id')->on('users');

table des contacts

$table->increments('id');

0 commentaires

2
votes

La clé étrangère doit être la même que l'ID de référence, et donc changez

$table->unsignedBigInteger('room_id')->unique();

en

$table->integer('room_id')->unique();

et cela fera l'affaire.

PS: vous en aurez un autre erreur

SQLSTATE [42S01]: table ou vue de base existe déjà: 1050 Table ...

il suffit de supprimer la table et d'exécuter php artisan migrate


0 commentaires