Я пытаюсь создать внешние ключи в Laravel, однако при переносе таблицы с помощью artisan
я следующую ошибку:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign
key (`user_id`) references `users` (`id`))
Мой код миграции таков:
файл миграции приоритетов
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
файл миграции пользователей
public function up()
{
//
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('email');
$table->string('first_name');
$table->string('password');
$table->string('email_code');
$table->string('time_created');
$table->string('ip');
$table->string('confirmed');
$table->string('user_role');
$table->string('salt');
$table->string('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schemea::drop('users');
}
Любые идеи относительно того, что я сделал неправильно, я хочу получить это прямо сейчас, так как у меня есть много таблиц, которые мне нужно создать, например, пользователи, клиенты, проекты, задачи, статусы, приоритеты, типы, команды. В идеале я хочу создать таблицы, которые содержат эти данные с внешними ключами, т.е.clients_project
project_tasks
т. И т. Д.
Надеюсь, кто-то может помочь мне начать.
Schema::table
метод помогло! Спасибо!$table->unsignedBigInteger('user_id')
если ваш user.idbigIncrements
Вопрос уже ответил, но надеюсь, что это может помочь кому-то еще.
Эта ошибка произошла для меня, потому что я создал таблицу миграции с внешним ключом, прежде чем ключ существовал в качестве первичного ключа в ее исходной таблице. Миграции выполняются в том порядке, в котором они были созданы, как указано именем файла, сгенерированным после запуска
migrate:make
. Например2014_05_10_165709_create_student_table.php
.Решением было переименовать файл с внешним ключом в более раннее время, чем файл с первичным ключом, как рекомендовано здесь: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Я думаю, что я также должен был добавить в
$table->engine = 'InnoDB';
источник
Laravel ^ 5.8
пример
Представим, что вы создаете простое приложение на основе ролей, и вам нужно сослаться на user_id в таблице PIVOT "role_user" .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Как вы можете видеть, закомментированная строка выдаст исключение запроса, потому что, как упоминалось в примечаниях по обновлению, столбцы внешнего ключа должны быть одного типа , поэтому вам нужно либо изменить внешний ключ (в данном примере это user_id ) на bigInteger в таблице role_user или измените метод bigIncrements на метод приращений в таблице users и используйте закомментированную строку в сводной таблице, решать вам.
Я надеюсь, что смог прояснить этот вопрос для вас.
источник
Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); }
Это сработало. Спасибо.В моем случае проблема заключалась в том, что в основной таблице уже были записи, и я заставлял новый столбец не иметь значение NULL. Поэтому добавление -> nullable () в новый столбец помогло. В примере вопроса будет что-то вроде этого:
$table->integer('user_id')->unsigned()->nullable();
или:
$table->unsignedInteger('user_id')->nullable();
Надеюсь, это кому-нибудь поможет!
источник
В моем случае проблема заключалась в том, что автоматически генерируемая миграция для
users
таблицыПоэтому мне пришлось изменить тип столбца
заставить мою миграцию с внешним ключом работать.
Это с laravel
5.8.2
источник
В моем случае проблема была в сроках миграции, будьте осторожны, при создании миграций сначала создайте дочернюю миграцию, чем базовую миграцию. Потому что, если вы сначала создадите базовую миграцию, у которой ваш внешний ключ будет искать дочернюю таблицу, и не будет таблицы, которая затем выдаст исключение.
Дальше больше:
Когда вы создаете миграцию, у нее есть отметка времени в начале. Допустим, вы создали кошку миграции, чтобы она выглядела
2015_08_19_075954_the_cats_time.php
и имела такой кодИ после создания базовой таблицы вы создаете другую породу миграции, которая является дочерней таблицей, у которой есть своя собственная отметка времени и даты создания. Код будет выглядеть так:
Кажется, что обе таблицы верны, но при запуске php artisan migrate . Это вызовет исключение, потому что миграция сначала создаст базовую таблицу в вашей базе данных, потому что вы сначала создали эту миграцию, и наша базовая таблица имеет ограничение внешнего ключа, которое будет искать дочернюю таблицу, а дочерняя таблица не существует, что, вероятно, исключение..
Так:
сделано это будет работать
источник
В моем случае я просто изменяю порядок миграции, выполняемой вручную, поэтому сначала создаются таблицы пользователей.
В папке database / migrations / ваше имя файла миграции имеет следующий формат: year_month_day_hhmmss_create_XXXX_table.php
Просто переименуйте файл создания пользователя, чтобы дата создания таблицы приоритетов таблицы была установлена позже, чем дата пользователя (достаточно даже одной секунды позже)
источник
В laravel 5.8 users_table использует
bigIncrements('id')
тип данных для первичного ключа. Так что, когда вы хотите сослаться на ограничение внешнего ключа, вашuser_id
столбец должен бытьunsignedBigInteger('user_id')
типом.источник
У меня была та же проблема с использованием Laravel 5.8. После более пристального взгляда на документы по Laravel, более того, здесь Migrations & bigIncrements . Я решил это путем добавления первичных ключей "$ table-> bigIncrements ('id')" к каждой отдельной таблице, которая связана с таблицей "users" и ее ассоциациями, в моем случае с таблицей "role" . Наконец, у меня был «$ table-> unsignedBigInteger» для привязки ролей к пользователям («многие ко многим»), то есть к таблице «role_user» .
источник
У меня была эта проблема с laravel 5.8, и я исправил этот код, как показано здесь в документации по Laravel , куда бы я ни добавлял внешний ключ.
тогда я побежал
$ php artisan migrate:refresh
Поскольку этот синтаксис довольно многословен, Laravel предоставляет дополнительные, более краткие методы, которые используют соглашение для обеспечения лучшего опыта разработчика. Пример выше может быть написан так:
источник
Использование Laravel 5.3 было той же проблемой.
Решением было использовать unsignedInteger вместо integer ('name') -> unsigned () .
Так вот что сработало
Причина, по которой это сработало, заключается в том, что при использовании целого числа («имя») -> без знака столбец, созданный в таблице, имел длину 11, а при использовании unsigedInteger («имя») столбец имел длину 10.
Длина 10 - это длина для первичных ключей при использовании Laravel, поэтому длина столбцов совпадает.
источник
Эта ошибка произошла для меня, потому что - хотя таблица, которую я пытался создать, была InnoDB - внешняя таблица, к которой я пытался связать ее, была таблицей MyISAM!
источник
Мы не можем добавлять отношения, пока не будут созданы связанные таблицы. Laravel запускает миграции по порядку файлов миграции. Поэтому, если вы хотите создать связь с таблицей, которая существует во 2-м файле миграции, это не удастся.
Я столкнулся с той же проблемой, поэтому я создал еще один файл миграции, чтобы указать все отношения.
источник
Имейте в виду: когда Laravel устанавливает таблицу, используя
что является стандартным в большинстве миграций, это установит поле целого числа без знака. Поэтому при создании внешней ссылки из другой таблицы на это поле убедитесь, что в ссылочной таблице вы задали для поля значение UnsignedInteger, а не (как я предполагал, поле) UnsignedBigInteger.
Например: в файле миграции 2018_12_12_123456_create_users_table.php:
Затем в файле миграции 2018_12_12_18000000_create_permissions_table.php, который устанавливает внешнюю ссылку для пользователей:
источник
Вы должны написать таким образом
Поле внешнего ключа должно быть без знака , надеюсь, это поможет !!
источник
Для добавления ограничения внешнего ключа в laravel у меня сработало следующее:
Создайте столбец для внешнего ключа следующим образом:
Добавление строки ограничения сразу после (1) т.е.
источник
я знаю, что это старый вопрос, но убедитесь, что если вы работаете со ссылками, то определен соответствующий движок поддержки. установить механизм innodb для обеих таблиц и один и тот же тип данных для ссылочных столбцов
источник
Введя здесь несколько лет спустя после первоначального вопроса, используя laravel 5.1, у меня была та же самая ошибка, поскольку мои миграции были произведены на компьютере с тем же кодом даты. Я просмотрел все предложенные решения, а затем провел рефакторинг, чтобы найти источник ошибок.
В следующих laracasts и при чтении этих постов я считаю, что правильный ответ похож на ответ Вики, за исключением того, что вам не нужно добавлять отдельный вызов схемы. Вам не нужно накрывать на стол Innodb, я полагаю, что сейчас это делает Laravel.
Миграции просто необходимо правильно рассчитать, что означает, что вы измените код даты вверх (позже) в имени файла для таблиц, для которых вам нужны внешние ключи. В качестве альтернативы или дополнения, опустите код даты для таблиц, которым не нужны внешние ключи.
Преимущество в изменении кода даты состоит в том, что ваш код миграции будет легче читать и поддерживать.
Пока мой код работает, настроив временной код так, чтобы отодвигать миграции, которым нужны внешние ключи.
Однако у меня есть сотни таблиц, поэтому в самом конце у меня есть еще одна таблица для внешних ключей. Просто чтобы все пошло как надо. Я предполагаю, что вытащу те в правильный файл и изменю код даты, поскольку я проверяю их.
Вот пример: файл 2016_01_18_999999_create_product_options_table. Для этого нужно создать таблицу продуктов. Посмотрите на имена файлов.
таблица продуктов: сначала необходимо выполнить миграцию. 2015_01_18_000000_create_products_table
И, наконец, в самом конце файл, который я временно использую для решения проблем, который я буду реорганизовывать при написании тестов для моделей, которые я назвал 9999_99_99_999999_create_foreign_keys.php. Эти ключи комментируются, когда я их вытащил, но вы поняли.
источник
Так просто !!!
если вы впервые создали
'priorities'
файл миграции, Laravel сначала запустится,'priorities'
пока'users'
таблица не существует.Как это может добавить отношение к таблице, которая не существует!
Решение: вытащить коды внешних ключей из
'priorities'
таблицы. Ваш файл миграции должен быть таким:и добавьте в новый файл миграции, вот его имя
create_prioritiesForeignKey_table
и добавьте эти коды:источник
удостоверьтесь, что ваш столбец foreing находится над широким диапазоном столбца ключа foreing
I означает, что ваш foreingkey (во второй таблице) должен быть того же типа, что и ваш ponter pricipal key (в первой таблице)
Ваш основной ключ указателя должен быть добавлен без знака, позвольте мне показать:
на вашей ПЕРВОЙ таблице миграции:
на вашей ВТОРОЙ таблице миграции:
ДРУГОЙ ПРИМЕР, ЧТОБЫ УВИДЕТЬ РАЗНИЦУ
на вашей ПЕРВОЙ таблице миграции:
на вашей ВТОРОЙ таблице миграции:
ПОСМОТРЕТЬ ЧИСЛО MYSQL ТАБЛИЦА ДИАПАЗОНОВ
источник
Одна вещь, которую я заметил, состоит в том, что, если таблицы используют другой механизм, чем ограничение внешнего ключа не работает.
Например, если одна таблица использует:
А другой использует
сгенерирует ошибку:
Вы можете исправить это, просто добавив InnoDB в конце создания таблицы следующим образом:
источник
В моем случае я ссылался на целочисленный
id
столбец в строковомuser_id
столбце. Я изменился:$table->string('user_id')
чтобы:
$table->integer('user_id')->unsigned();
Надеюсь, это поможет кому-то!
источник
Суть в том, что внешний метод используется
ALTER_TABLE
для преобразования ранее существующего поля во внешний ключ. Таким образом, вы должны определить тип таблицы, прежде чем применять внешний ключ. Тем не менее, это не должно быть в отдельномSchema::
вызове. Вы можете сделать оба в рамках создания, как это:Также обратите внимание, что тип
user_id
установлен в unsigned, чтобы соответствовать внешнему ключу.источник
Вы можете напрямую передать логический параметр в столбце целых чисел, говоря, что он должен быть без знака или нет. В laravel 5.4 следующий код решил мою проблему.
Здесь второй параметр false представляет, что он не должен быть автоинкрементным, а третий параметр true представляет, что он должен быть без знака. Вы можете сохранить ограничение внешнего ключа в той же миграции или отделить его. Это работает на обоих.
источник
Если ни одно из приведенных выше решений не подходит для новичков, проверьте, имеют ли оба идентификатора одинаковый тип: оба являются
integer
или оба являютсяbigInteger
... Вы можете получить что-то вроде этого:Основная таблица (пользователи, например)
Детский стол (приоритеты например)
Этот запрос не будет выполнен, потому что
users.id
являетсяBIG INTEGER
тогда, когдаpriorities.user_id
являетсяINTEGER
.Правильный запрос в этом случае будет следующим:
источник
В моем случае это не сработало, пока я не запустил команду
таким образом, вы можете оставить внешние ключи внутри схемы создания
источник
Это также может быть ваш заказ создания миграции. Если вы сначала создадите таблицу приоритетов, а затем таблицу пользователей, то это будет неправильно. Из-за первой миграции ищем таблицу пользователей. Таким образом, вы должны изменить порядок миграции на
каталог
источник
Для меня столбец таблицы, на который ссылалась моя дочерняя таблица, не был проиндексирован.
Не обращайте внимания на ужасные названия, это из другой ужасно разработанной системы.
источник
Иногда эта ошибка может возникать из-за последовательности миграций.
Как пользователи и порядок две таблицы
У таблицы заказов есть внешний ключ пользователей (во время миграции, если таблица заказов будет перенесена первой, это вызовет проблему, потому что нет пользователей, соответствующих внешнему ключу)
Решение: просто поместите таблицу обновления заказа под пользователями для обновления
Пример: в моем случае таблицы образования и университета Таблица образования
В университете
источник
Я думаю, что в ответах здесь отсутствует одна вещь, и, пожалуйста, исправьте меня, если я ошибаюсь, но внешние ключи должны быть проиндексированы в сводной таблице. По крайней мере, в MySQL, похоже, это так.
источник