Laravel Migration Внешнее ограничение ключа неправильно сформировано

При миграции моей БД появляется эта ошибка, ниже мой код сопровождается ошибкой, которую я получаю при попытке выполнить миграцию.

код

 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');
        });
    }  

Сообщение об ошибке

[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) 

Ответ 1

@JuanBonnett Ваш вопрос вдохновил меня на ответ, я принял на laravel, чтобы автоматизировать процесс, не учитывая время создания самого файла. Согласно рабочему процессу, еда будет создана перед таблицей (категориями), потому что я создал файл схемы (питание) перед категориями. это была моя ошибка.

Ответ 2

При создании новой таблицы в Laravel. Миграция будет сгенерирована следующим образом:

$table->bigIncrements('id');

Вместо (в старых версиях Laravel):

$table->increments('id');

При использовании bigIncrements внешний ключ ожидает bigInteger вместо целого числа. Итак, ваш код будет выглядеть так:

public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedBigInteger('user_id'); //changed this line
            $table->unsignedBigInteger('category_id'); //changed this line
            $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');
        });
    }  

Вы также можете использовать increments вместо bigIncrements как сказал Кико Седжо.

Разница между Integer и BigInteger заключается в размере:

  • int => 32-разрядный
  • bigint => 64-битный

Ответ 3

просто добавьте ->unsigned()->index() в конец внешнего ключа, и он будет работать

Ответ 4

Для меня все было в правильном порядке, но это все еще не сработало. Затем я узнал, что первичным ключом должен быть неподписанный.

//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');

Ответ 5

В моем случае новая конвенция Laravel вызвала эту ошибку.

Простым обменом id создания таблицы все получилось.

$table->increments('id'); // ok

вместо:

$table->bigIncrements('id'); // was the error.

Уже работаю с Laravel v5.8, такой ошибки раньше не было.

Ответ 6

Миграции должны создаваться сверху вниз.

Сначала создайте миграцию для таблиц, которые не принадлежат никому.

Затем создайте миграции для таблиц, принадлежащих предыдущему.


Упрощенный ответ на проблему с движением таблицы:

Чтобы установить механизм хранения для таблицы, установите свойство engine в построителе схемы:

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

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

Из Laravel Docs: https://laravel.com/docs/5.2/migrations

Ответ 7

если вы используете ->onDelete('set null') в определении внешнего ключа, убедитесь, что поле внешнего ключа 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');

Ответ 8

Вы должны создать свою миграцию в порядке например, я хочу, чтобы мой users имел поле role_id, которое находится в моей таблице roles

I сначала начнет выполнять мою миграцию роли php artisan make:migration create_roles_table --create=roles

то моя вторая миграция пользователей php artisan make:migration create_users_table --create=users

php artisan migration будет выполняться с использованием порядка созданных файлов 2017_08_22_074128 _create_roles_table.php и 2017_08_22_134306 _create_users_table проверить заказ datetime, который будет порядком выполнения.

файлы 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');
    });
}

Ответ 9

В моем случае проблема заключалась в том, что одна из ссылочных таблиц была InnoDB, а другая была MyISAM.

MyISAM не поддерживает отношения внешних ключей.

Итак, теперь обе таблицы InnoDB. Проблема решена.

Ответ 10

Может быть, это может помочь любому, кто приземлился здесь: я просто испытал эту же проблему, и в моем случае это было то, что у меня было (составное) уникальное ограничение, установленное в столбце внешнего ключа ПЕРЕД ключом внешнего ключа. Я разрешил проблему, установив "уникальное" утверждение, ПОСЛЕ "ЗАЯВЛЕНИЕ".

Работает:

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

Не работает:

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

Ответ 11

Я получил то же сообщение для проблемы с типом данных.

Я использовал bigIncrements() для 'id', и когда я использовал его как внешний ключ (использовал bigInteger()), я получил ошибку.

Я нашел решение, bigIncrements() возвращает unsignedBigInteger. Поэтому необходимо использовать unsignedBigInteger() вместо bigInteger() во внешнем ключе

Поделиться этим, потому что это может помочь другим

Ответ 12

Добавить → nullable() в поле и убедиться, что все поля, к которым вы обращаетесь, действительно существуют.

Ответ 13

Порядок создания файлов миграции должен быть отсортирован, и внешний ключ должен иметь точно такое же свойство, что и первичный ключ в другой таблице.

Ответ 14

Помните, что это важно, чтобы ссылочные поля и поля ссылок имели одинаковый тип данных.

Ответ 15

Сначала вы должны создать таблицу категорий и пользователей при создании "блюд".

Чтобы решить эту проблему, вы должны переименовать файлы миграции категорий и пользователей до даты, предшествующей файлу миграции еды, которые создают их перед таблицей еды.


образец:
2019_04_10_050958_create_users_table 
2019_04_10_051958_create_categories_table
2019_04_10_052958_create_meals_table