Подтвердить что ты не робот

Иностранные ключи в проблеме миграции 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();
    });
4b9b3361

Ответ 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 уверен, что ссылочный ключ уже существует. и вам не нужно бросать таблицы во время ошибок ремесленника.