Миграция Laravel (errno: 150 "Внешнее ограничение ключа неверно сформировано")

У меня есть таблица заказов и есть sell_shipping_labels который ссылается на orders.id как на иностранную. Однако, когда я запускаю миграцию Laravel, я получаю ужасный код ошибки:

[Осветите\Database\QueryException]
SQLSTATE [HY000]: Общая ошибка: 1005 Не cheapbooks_test создать таблицу cheapbooks_test. #sql-b5b_b2a (errno: 150 "Ограничение внешнего ключа неверно сформировано") (SQL: alter table sell_shipping_labels добавить ограничение sell_shipping_labels_order_id_foreign внешний ключ (order_id) ссылки orders (id))

[Учение\DBAL\Driver\PDOException]
SQLSTATE [HY000]: Общая ошибка: 1005 Не cheapbooks_test создать таблицу cheapbooks_test. #sql-b5b_b2a (errno: 150 "Ограничение внешнего ключа неверно сформировано")

Это моя таблица таблиц orders:

   Schema::create('orders', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id');
        $table->integer('book_id');
        $table->integer('status_id');
        $table->double('payment_amount')->nullable();
        $table->timestamp('received_at')->nullable();
        $table->timestamp('paid_at')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });

И это моя схема sell_shipping_labels:

Schema::create('sell_shipping_labels', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('order_id');
        $table->string('shippo_object_id');
        $table->string('label_url');
        $table->string('tracking_url');
        $table->string('tracking_number');
        $table->timestamp('arrived_at');
        $table->timestamps();
        $table->softDeletes();

        $table->foreign('order_id')->references('id')->on('orders');
    });
}

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

Ответы

Ответ 1

Поскольку increments() создает столбец без знака, вам нужно также определить столбец внешнего ключа как целое без знака:

$table->unsignedInteger('order_id');

Или же:

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

https://laravel.com/docs/5.5/migrations#foreign-key-constraints

Ответ 2

внешний ключ должен быть "unsignedBigInteger", и он будет исправлен, примерно так:

$table->unsignedBigInteger('user_id');

$table->foreign('user_id')->references('id')->on('users');

Ответ 3

Первичный и внешний ключи должны быть одного типа данных.

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

Если в laravel 5.8 по умолчанию используется bigIncrements при создании новой миграции (см. этот запрос на извлечение), вам следует убедиться, что ваш foreign key также является big_increment, иначе вы получите ошибку.

Таблица users:

Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');

    ...

}

Таблица orders:

Schema::create('orders', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id');

    ...

    $table->foreign('user_id')->references('id')->on('users');
}

Надеюсь, это поможет.

Ответ 4

Laravel 5.8.3 поставляется с $table->bigIncrements('id');

изменить на

$table->increments('id');
$table->integer('order_id')->unsigned();

Ответ 5

Я также получал ту же ошибку. Что я делал в таблице пользователей,

$table->unsignedInteger('role_id')->default(2); table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');

Но я создал таблицу ролей после создания таблицы пользователей. Итак, я отредактировал дату имени файла миграции роли перед датой имени пользователя в таблице пользователей. Как это,

2013_01_22_091213_create_roles_table.php
2014_10_12_000000_create_users_table.php

И наконец это работает. Может быть, когда-нибудь вы можете получить эту проблему. Итак, я отправил это.

Ответ 6

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

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

Ответ 7

Для тех, кто смотрит на это с помощью laravel 5.8.x Я исправил это, изменив это

$table->unsignedInteger('foreign_id');

к этому

$table->unsignedBigInteger('foreign_id');

Это связано с использованием BigIncrements. Вместо этого вы можете удалить шанс bigIncrements для приращений по обе стороны отношения

Ответ 8

Для тех, кто отметил ответ, не работает:

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

Ответ 9

  1. Файлы миграции должны быть созданы таким образом, чтобы родительская миграция шла первой, а затем файл миграции с внешним ключом.
  2. Внешний ключ и первичный идентификатор в другой таблице должны иметь точно такое же свойство. Если первичным идентификатором является инкремент, сделайте внешний ключ целым числом ('xxx_id') → unsigned();

Ответ 10

У меня была та же проблема, и я исправил проблему, задав тип базы данных innoDB

Таблицы, созданные до перенастройки, где "MyISAM из устаревшей системы и перенастроенные, по умолчанию являются innoDB, поэтому в моем случае проблема сочетания типов таблиц была проблемой.

Ответ 11

Я столкнулся с этой проблемой сегодня. Я проверил все предложенные решения, такие как ссылочный ключ и внешний ключ, один и тот же тип данных, одинаковые параметры сортировки в ядре базы данных и конфигурации laravel (database.php), порядок дат миграции и другие возможные ошибки, но любой был моим решением! Последнее, что я обнаружил, это ограничения onUpdate и onDelete, которые привели к миграции. Удалив их, моя проблема решена!

Ответ 12

Освещение\База данных \QueryException: SQLSTATE [HY000]: Общая ошибка: 1005 Невозможно создать таблицу myblog. #sql-23f4_201 (errno: 150 "Ограничение внешнего ключа сформировано неправильно") (SQL: изменить таблицу category_posts добавить ограничение category_posts_post_id_foreign внешний ключ (post_id) ссылается на posts (id) при удалении каскада)

я столкнулся с этой проблемой, пожалуйста, помогите мне?

Ответ 13

Я столкнулся с той же проблемой сегодня. Моя версия Laravel - 5.8.29. Я решил проблему, выполнив:

$table->bigIncrements('id'); //current table primary key and id
$table->unsignedBigInteger('user_id'); // foreigh key
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

Надеюсь, это работает.

Ответ 14

Если проблема все еще не решена, попробуйте. вам нужно создать последнюю связанную таблицу.

Сначала вы должны создать ордера, а затем создать таблицу sell_shipping_labels

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

Ответ 15

[![enter image description here][1]][1]
public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();


        });
    }

I changed $table->bigIncrements('id') to $table->Increments('id')
For this user_id of files table become same integer type as user table field id. After this command worked.

   public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }



For the second table
 {
        Schema::create('files', function (Blueprint $table) {
            $table->increments('id');

});

            Schema::table('files', function($table) {
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
           });
    }

enter image description here

Ответ 16

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

Всегда следите за тем, чтобы миграция файла, на который должны накладываться внешние ограничения, выполнялась после родительской миграции. А для последнего убедитесь, что это unsignedBigInteger, хотя прежняя версия laravel (& lt; 5.4) могла игнорировать эту ошибку приведения типа.