2015-09-19 7 views
7

При миграции моей БД эта ошибка появляется, ниже мой код сопровождается ошибкой, которую я получаю при попытке выполнить миграцию.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) 
+0

Есть категории и пользователи уже созданы? –

+0

Создает пользователей, а затем получает питание и получает эту ошибку, после чего создание останавливается, и после удаления (category_id) миграция завершена успешно. –

ответ

7

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

+0

так глупо :(, это должно быть похоже на сеялку базы данных. Мы должны определить заказы. –

0

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

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

Итак, сейчас обе таблицы: InnoDB. Задача решена.

+0

Как вы изменили настройку? – dakab

+0

Это не параметр, это свойство таблицы, это запрос для преобразования таблицы в MySQL: 'ALTER TABLE имя_таблицы ENGINE = InnoDB;' – nwrman

1

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

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

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


упрощенный ответ на проблему таблицы двигателя:

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

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

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

От Laravel Docs: https://laravel.com/docs/5.2/migrations

+0

Можем ли мы контролировать поток генерации таблицы (как вы сказали сверху вниз создание) Как –

+0

удивительным Я изменил имя миграции файлов (время), и он работал?! , Спасибо :) –

+0

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

1

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

работы:

$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'); 
5

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

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

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

+0

index() избыточно, потому что внешний ключ будет генерировать по умолчанию индекс в этом столбце –

+0

Для меня просто добавление - > unsigned(). –

0

если вы используете ->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'); 
1

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

Я первый старт, чтобы моя роль миграции 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 проверить дату это будет порядок выполнения.

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

Add -> обнуляемым() на своем поле и убедитесь, что все поля, которые вы имеете в виду на самом деле существует.