Миграция 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
- Файлы миграции должны быть созданы таким образом, чтобы родительская миграция шла первой, а затем файл миграции с внешним ключом.
- Внешний ключ и первичный идентификатор в другой таблице должны иметь точно такое же свойство. Если первичным идентификатором является инкремент, сделайте внешний ключ целым числом ('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');
});
}
Ответ 16
В большинстве случаев причиной этой ошибки обычно является порядок, в котором перечислены файлы миграции, или ошибка из-за приведения типов.
Всегда следите за тем, чтобы миграция файла, на который должны накладываться внешние ограничения, выполнялась после родительской миграции.
А для последнего убедитесь, что это unsignedBigInteger, хотя прежняя версия laravel (& lt; 5.4) могла игнорировать эту ошибку приведения типа.