Иностранные ключи в проблеме миграции Laravel 4
Я только что создал новый проект Laravel 4, и я нахожу странные вещи, связанные с внешним ключом компоновщика схемы. Если я использую метод ->foreign()
в любой из моих миграций, я получаю брошенные ошибки MySQL 150 и общую ошибку 1005. Согласно документации на laravel.com/docs, должен работать два сценария внизу? Кто-нибудь знает, почему они этого не делают?
Выполняется следующее:
Schema::create('areas', function($table)
{
$table->engine ='InnoDB';
$table->increments('id');
$table->integer('region_id')->references('id')->on('regions');
$table->string('name', 160);
$table->timestamps();
});
Но эти два не работают:
Schema::create('areas', function($table)
{
$table->engine ='InnoDB';
$table->increments('id');
$table->foreign('region_id')->references('id')->on('regions');
$table->string('name', 160);
$table->timestamps();
});
Schema::create('areas', function($table)
{
$table->engine ='InnoDB';
$table->increments('id');
$table->integer('region_id');
$table->foreign('region_id')->references('id')->on('regions');
$table->string('name', 160);
$table->timestamps();
});
Ответы
Ответ 1
Проверьте тип id
. Laravel 4 создает инкрементный id с int (10) без знака.
Если вы создадите базовое целое число и попытаетесь поместить на него внешний ключ, он не будет работать.
Как указано в документации по эта ссылка, вы должны создать чужой идентификатор с $table->unsignedInteger(YOUR_ID_NAME);
, чтобы заставить его работать.
Ответ 2
Также некоторые ответы по этому вопросу "Общая ошибка: 1005 Не удается создать таблицу" Использование сборки схемы Laravel и внешних ключей
Резюме приведенных там ответов, включая мои:
-
Внешние ключи обычно требуют InnoDb, поэтому установите свой механизм по умолчанию или явно укажите
$table->engine = 'InnoDB';
Если ваша таблица уже создана и по умолчанию установлена в MyISAM, вам может потребоваться ее изменить.
-
Для внешних ключей требуется, чтобы ссылочная таблица существовала. Перед созданием ключа убедитесь, что таблица с привязкой создана в более ранней миграции. Рассмотрите возможность создания ключей в отдельной миграции, чтобы убедиться.
-
Для внешних ключей требуется, чтобы тип данных был конгруэнтным. Проверьте, является ли ссылочное поле одним и тем же типом, независимо от того, была ли его подпись или без знака, является ли длина одинаковой (или меньше).
-
Если вы переключаетесь между миграциями ручного кодирования и используете генераторы, убедитесь, что вы проверяете тип идентификатора, который используете. Artisan по умолчанию использует increments(), но Jeffrey Way предпочитает integer ('id', true).
Ответ 3
Была такая же проблема день назад.
Корень проблемы: столбец с внешним ключом должен быть того же типа, что и этот ключ.
И у вас разные типы: INT/UNSIGNED INT
это делает id a UNSIGNED INT
$table->increments('id');
и это делает region_id a INT
$table->integer('region_id')->references('id')->on('regions');
Чтобы решить эту проблему, сделайте region_id a UNSIGNED INT
слишком
$table->integer('region_id')->unsigned()->references('id')->on('regions');
^^^^^^^^^ note here
В документации Laravel укажите об этом:
Примечание. При создании внешнего ключа, который ссылается на добавочное целое число, не забудьте всегда делать столбец внешнего ключа без знака.
Ответ 4
Это работает, но иногда вам просто нужно быть осторожным и пытаться понять, что происходит за сценой.
Как я уже сказал в своем комментарии. Когда вы впервые запускали миграцию, не создавая соответствующий столбец, службы миграции Laravel создали вашу таблицу, а затем, когда вы попытались выполнить миграцию, она всегда будет давать вам сообщение о том, что таблица уже существует.
Итак, вам просто нужно drop table areas
и снова запустить php artisan migrate
, чтобы исправить все.
EDIT:
Я только что создал вашу миграцию (ниже) здесь, и она сработала.
Как вы можете видеть, я не использую MySQL, поэтому это проблема MySQL. Проверьте документацию по внешним ключам MySQL, чтобы узнать, соответствуют ли ваши метаданные требованиям InnoDB: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html.
<?php
use Illuminate\Database\Migrations\Migration;
class CreateAreasTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('regions', function($table)
{
// $table->engine = 'InnoDB';
$table->increments('id');
$table->string('name', 160)->unique();
$table->timestamps();
});
Schema::create('areas', function($table)
{
// $table->engine ='InnoDB';
$table->increments('id');
$table->integer('region_id');
$table->foreign('region_id')->references('id')->on('regions');
$table->string('name', 160);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('areas');
Schema::drop('regions');
}
}
![enter image description here]()
Ответ 5
antonio carlos прав, убедитесь, что вы создали первую ссылочную таблицу своего внешнего ключа.
попробуйте сначала перенести таблицы без внешних ключей, затем выполните другую миграцию, назначив внешние ключи. в этом состоянии, laravel уверен, что ссылочный ключ уже существует. и вам не нужно бросать таблицы во время ошибок ремесленника.