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

"Общая ошибка: 1005 Не удается создать таблицу" Использование сборки схемы Laravel и внешних ключей

По существу, у меня такая же проблема, как у этого парня, минус префикс таблицы. Поскольку у меня нет префикса таблицы, его исправление не работает. http://forums.laravel.com/viewtopic.php?id=972

Я пытаюсь создать таблицу с помощью Laravel Schema Builder следующим образом:

Schema::create('lessons', function($table)
{
    $table->increments('id');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->timestamps();
});

Schema::create('tutorials', function($table)
{
    $table->increments('id');
    $table->integer('author');
    $table->integer('lesson');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->string('tagline')->nullable();
    $table->text('content')->nullable();
    $table->text('attachments')->nullable();
    $table->timestamps();
});

Schema::table('tutorials', function($table)
{
    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

Проблема заключается в том, что когда я запускаю этот код (в маршруте /setup ), я получаю следующую ошибку:

SQLSTATE[HY000]: General error: 1005 Can't create table 'tutorials.#sql-2cff_da' (errno: 150)

SQL: ALTER TABLE `tutorials` ADD CONSTRAINT tutorials_author_foreign FOREIGN KEY (`author`) REFERENCES `users` (`id`)

Bindings: array (
)

Основываясь на сообщениях в Интернете и ограниченной документации о том, как настроить отношения Laravel Eloquent, я не уверен, что я делаю неправильно...

users уже существует и имеет поле id, которое auto_increment. Я также настраиваю свои модели с правильными отношениями (belongs_to и has_many), но насколько я могу сказать, это не проблема - это настройка базы данных. БД - InnoDB.

Что я делаю неправильно с внешним ключом?

4b9b3361

Ответ 1

Я не уверен на 100%, если это причины, по которым это происходит, но пара указателей. Если вы используете более старую версию mySQL в качестве базы данных, реализация таблицы по умолчанию - myISAM, которая не поддерживает ограничения внешнего ключа. Поскольку ваши сценарии не работают при назначении внешнего ключа, вам лучше сказать, что вы хотите, чтобы INNODB использовался в качестве механизма с использованием этого синтаксиса в методе создания схемы.

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

    $table->increments('id');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->timestamps();
});

Это, надеюсь, облегчит проблемы, которые у вас есть.

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

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

    $table->increments('id');
    $table->integer('author');
    $table->integer('lesson');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->string('tagline')->nullable();
    $table->text('content')->nullable();
    $table->text('attachments')->nullable();
    $table->timestamps();

    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

Надеюсь, что это поможет вам решить вашу проблему.

Ответ 2

У меня такая же проблема. Я только заметил в нижней части Laravel Schema docs следующее примечание:

Примечание. Поле, на которое ссылается внешний ключ, скорее всего, является автоматическим приращением и, следовательно, автоматически целым числом без знака. Не забудьте создать поле внешнего ключа с unsigned(), так как оба поля должны быть одного и того же типа, для обоих таблиц должен быть установлен указатель на InnoDB, а таблица с привязкой должна быть создана до таблицы с внешним ключом.

Для меня, как только я установил поля внешнего ключа как таковые:

$table->integer('author')->unsigned();

У меня не было проблем.

EDIT: также убедитесь, что поля в внешней таблице уже созданы, иначе это может завершиться с той же ошибкой.

Ответ 3

Резюме ответов, уже перечисленных, плюс мой:

  • Внешние ключи обычно требуют InnoDb, поэтому установите свой механизм по умолчанию или явно укажите

    $table- > engine = 'InnoDB';

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

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

  • Если вы переключаетесь между миграциями ручного кодирования и используете генераторы, убедитесь, что вы проверяете тип идентификатора, который используете. Artisan по умолчанию использует increments(), но Jeffrey Way предпочитает integer ('id', true).

Ответ 4

Я тоже столкнулся с этой проблемой.

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

В вашем примере сначала должны быть созданы таблицы авторов и уроков.

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

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

Ответ 5

Я получил ту же ошибку, потому что забыл указать тип таблицы InnoDB в таблице, на которую ссылается:

$table->engine = 'InnoDB';

Ответ 6

Laravel5, MySQL55, CentOS65

в моем случае ошибки были такими же.

Ошибка: [Illuminate\Database\QueryException]
SQLSTATE [HY000]: Общая ошибка: 1005 Не удается создать таблицу 'nabsh. # sql-5b0_e' (errno: 121) (SQL: изменить таблицу usermeta добавить Ограничить внешний ключ usermeta_uid_foreign (uid) ref users (id) при удалении каскада).

Я нашел хороший совет в этой разрешенной проблеме: ОШИБКА: Ошибка 1005: невозможно создать таблицу (errno: 121)

Совет. Вы получите это сообщение, если пытаетесь добавить ограничение с именем, которое уже использовалось где-то еще.

в моем случае эта ошибка означает, что ограничение, которое пыталось добавить, уже существует где-то (но я не мог их видеть нигде).

Я скопировал выходной запрос на ошибку и выполнил его в продолжении pro, а затем, надеюсь, снова увидел ту же ошибку. как подсказка говорит, что я сменил имя ограничения на что-то еще, тогда оно затронуло отсутствие ошибки, поэтому возникла проблема с построением имени ограничения в laravel5 + MySQL55 + CentOS65.

Решение: попробуйте переименовать ограничения, посылая второй параметр по чужему методу в схеме таблицы.

Schema::table('tutorials', function($table)
{
    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

to →

Schema::table('tutorials', function($table)
{
    $table->foreign('author', 'fk_tutorials_author')->references('id')->on('users');
    $table->foreign('lesson', 'fk_tutorials_lesson')->references('id')->on('lessons');
});

Надеюсь, это поможет. он работает в моем случае

Ответ 7

Это случилось со мной в миграции Yii Framework 1.x. Оказалось, что аналогично решениям Laravel над ним может быть вызвано

  • неправильно написанное (или еще не существующее) имя таблицы
  • неправильное (или еще не существующее) имя столбца
  • дублировать имя внешнего ключа в той же базе данных, которая используется в разных таблицах

Ответ 8

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

Ответ 9

Самый простой способ - отключить проверки внешнего ключа:

DB::statement('set foreign_key_checks=0');

Schema::table( ... );

DB::statement('set foreign_key_checks=1');

Ответ 10

Вот что я делаю в Laravel 5:

// CREATING TABLE
Schema::create('your_table_name', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id'); // index field example sample
    $table->string('field2'); // some varchar/string field sample
    $table->integer('field3'); // some integer field sample
    $table->integer('field_some_table_id')->unsigned; //for field that contains foreign key constraint
});

// FOREIGN KEY CONSTRAINT
Schema::table('stock', function ($table) {
    $table->foreign('field_some_table_id')->references('id')->on('some_table')->onDelete('cascade')->onUpdate('cascade');
});

Что все для заключения, и это работает для меня.

Ответ 11

Вы должны указать целое число без знака в Laravel 5.4, например:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('post_id');
        $table->text('title');
        $table->text('text');
        $table->integer('employee_post_id_number')->unsigned();
        $table->foreign('employee_post_id_number')->references 
        ('employee_id_number')->on('employees');
        $table->timestamps();
    });
}