web-dev-qa-db-fra.com

La contrainte de clé étrangère de migration de Laravel est mal formée

Lors de la migration de ma base de données, cette erreur apparaît. Ci-dessous se trouve mon code suivi de l’erreur que j’obtiens en essayant d’exécuter la migration.

Code

 public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->string('title');
            $table->string('body');
            $table->string('meal_av');
            $table->timestamps();

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

            $table->foreign('category_id')
                ->references('id')
                ->on('categories')
                ->onDelete('cascade');
        });
    }  

Message d'erreur

[Illuminate\Database\QueryException]                                         
      SQLSTATE[HY000]: General error: 1005 Can't create table `meal`.`#sql-11d2_1  
      4` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter   
      table `meals` add constraint meals_category_id_foreign foreign key (`catego  
      ry_id`) references `categories` (`id`) on delete cascade) 
16
Medo tareq

@JuanBonnett Votre question m'a inspiré à la réponse, j'ai adopté sur laravel pour automatiser le processus sans tenir compte de la date de création du fichier lui-même. Selon le flux de travail, les repas seront créés avant le tableau (catégories) car j'ai créé un fichier de schéma (repas). avant les catégories . c'était de ma faute.

14
Medo tareq

ajoutez simplement ->unsigned()->index() à la fin de la clé étrangère et cela fonctionnera

10
geekbro

Pour moi, tout était dans le bon ordre, mais cela ne fonctionnait toujours pas. Ensuite, j'ai découvert en bidouillant que la clé primaire devait être non signée.

//this didn't work
$table->integer('id')->unique();
$table->primary('id');

//this worked
$table->integer('id')->unsigned()->unique();
$table->primary('id');

//this worked 
$table->increments('id');
7
zamppe

Vous devez créer votre migration dans l’ordre Par exemple, je souhaite que ma users ait un champ role_id qui provient de ma table roles.

Je premier commence à faire migrer mon rôle php artisan make:migration create_roles_table --create=roles

puis ma deuxième migration d'utilisateur php artisan make:migration create_users_table --create=users

php artisan migration sera exécuté dans l'ordre des fichiers créés 2017_08_22_074128 _ create_roles_table.php et 2017_08_22_134306 _ create_users_table vérifie l'ordre de la date/heure, qui sera l'ordre d'exécution.

fichiers 2017_08_22_074128_create_roles_table.php

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name', 50);
        $table->timestamps();
    });
}

2017_08_22_134306_create_users_table

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('role_id')->unsigned();
        $table->string('name');
        $table->string('phone', 20)->unique();
        $table->string('password');
        $table->rememberToken();
        $table->boolean('active');
        $table->timestamps();
        $table->foreign('role_id')->references('id')->on('roles');
    });
}
4
Napster Scofield

Les migrations doivent être créées de haut en bas.

Commencez par créer les migrations pour les tables qui n'appartiennent à personne.

Créez ensuite les migrations pour les tables appartenant à la précédente. 


Réponse simplifiée au problème du moteur de table:

Pour définir le moteur de stockage d'une table, définissez la propriété du moteur dans le générateur de schéma:

Schema::create('users', function ($table) {
    $table->engine = 'InnoDB';

    $table->increments('id');
});

De Laravel Docs: https://laravel.com/docs/5.2/migrations

3
Manuel Azar

si vous utilisez ->onDelete('set null') dans votre définition de clé étrangère, assurez-vous que le champ de la clé étrangère est lui-même nullable()

//Column definition
$table->integer('user_id')->unsigned()->index()->nullable(); //index() is optional

//...
//...

//Foreign key 
$table->foreign('user_id')
      ->references('id')
      ->on('users')
      ->onDelete('set null');
2
aphoe

Cela peut peut-être aider les personnes qui débarquent ici: je viens de vivre le même problème et, dans mon cas, c’est que j’avais une contrainte unique (composite) définie sur la colonne de clé étrangère AVANT la contrainte de clé étrangère. J'ai résolu le problème en faisant placer la déclaration "unique" APRÈS la déclaration "étrangère".

Travaux:

$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
$table->unique(['step_id','lang']);

Ne fonctionne pas:

$table->unique(['step_id','lang']);
$table->foreign('step_id')->references('id')->on('steps')->onDelete('cascade');
1
Matthias

Dans mon cas, le problème était que l’une des tables référencées était InnoDB et l’autre était MyISAM .

MyISAM n'a pas de support pour les relations de clé étrangère.

Donc, maintenant les deux les tables sont InnoDB . Problème résolu.

1
nwrman

Ajoutez -> nullable () sur votre champ et assurez-vous que tous les champs auxquels vous faites référence existent vraiment.

0
Rafael Xavier

L'ordre de création des fichiers de migration doit être trié et la clé étrangère doit avoir exactement la même propriété que la clé primaire de l'autre table.

0
Ayenew Yihune