Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 30.03.2017 06:46:14

Ошибка SQLSTATE[42S21]

Формирую миграцию по изменению таблицы

php artisan make:migration ChangeArticlesTable --table=articles
Миграция происходит успешно.

Далее открываю файл миграции, вношу записи по формировании связи с другой таблицей
    $table->integer('user_id')->unsigned()->default(1);
    $table->foreign('user_id')->references('id')->on('users');         
     $table->integer('category_id')->unsigned()->default(1);
     $table->foreign('category_id')->references('id')->on('categories');
Дальше необходимо внести изменения командой
php artisan migrate

Но изменения не вносятся, появляется сообщение об ошибке:

[Illuminate\DATABASE\QueryException]
SQLSTATE[42S21]: COLUMN already EXISTS: 1060 Duplicate COLUMN name 'user_id'
(SQL: ALTER TABLE 'articles' ADD 'user_id' INT UNSIGNED NOT NULL DEFAULT ‘1’, ADD 'catego ry_id' INT UNSIGNED NOT NULL DEFAULT ’l’)

[PDOException]
SQLSTATE[42S21]: COLUMN already EXISTS: I960 Duplicate COLUMN name ’user_id'

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

Не в сети

#2 30.03.2017 07:45:50

Re: Ошибка SQLSTATE[42S21]

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

Не в сети

#3 30.03.2017 08:20:10

Re: Ошибка SQLSTATE[42S21]

constb пишет:

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

Благодарю! Правильно поправил меня, мне действительно нужно установить внешние ключи. Но тот алгоритм по внешним ключам который я делаю должен выполняться, но где-то ошибка. У меня вначале вообще не устанавливались таблицы, установил только когда перешел mySQL на 5.7-64. Не знаю, может быть есть какой то другой алгоритм действий есть по установлению внешних ключей.

Не в сети

#4 30.03.2017 10:09:57

skiphog
Откуда: Киров, Россия
Сообщений: 26

Re: Ошибка SQLSTATE[42S21]

SZV пишет:

... У меня вначале вообще не устанавливались таблицы, установил только когда перешел mySQL на 5.7-64

Документация https://laravel.com/docs/5.4/migrations#indexes

Laravel 5.4 по умолчанию использует кодировку utf8mb4, которая включает в себя поддержку смайлов "emoji"
Если вы хотите использовать mysql 5.6, то можно в AppServiceProvider => boot добавить Schema::defaultStringLength(191);
либо пойти в config => database и в настройках mysql сменить кодировку utf8mb4 на utf8 и collation на utf8_unicode_ci, но тогда поддержки "emoji" не будет...

Теперь, что касается миграции...

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

$table->integer('user_id')->unsigned()->default(1)->change();
*должен быть установлен doctrine/dbal
--
Если вам не нужно менять столбец, а нужно только связать ключи, то эту строку вообще удалите, но учтите, что для связывания user_id должен быть unsigned, иначе опять выскочит ошибка.

Не в сети

#5 30.03.2017 12:25:03

Re: Ошибка SQLSTATE[42S21]

skiphog пишет:
SZV пишет:

... У меня вначале вообще не устанавливались таблицы, установил только когда перешел mySQL на 5.7-64

Документация https://laravel.com/docs/5.4/migrations#indexes

Laravel 5.4 по умолчанию использует кодировку utf8mb4, которая включает в себя поддержку смайлов "emoji"
Если вы хотите использовать mysql 5.6, то можно в AppServiceProvider => boot добавить Schema::defaultStringLength(191);
либо пойти в config => database и в настройках mysql сменить кодировку utf8mb4 на utf8 и collation на utf8_unicode_ci, но тогда поддержки "emoji" не будет...

Теперь, что касается миграции...

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

$table->integer('user_id')->unsigned()->default(1)->change();
*должен быть установлен doctrine/dbal
--
Если вам не нужно менять столбец, а нужно только связать ключи, то эту строку вообще удалите, но учтите, что для связывания user_id должен быть unsigned, иначе опять выскочит ошибка.

Вы правы. Добавил ->change(). Немного продвминулся в решении проблемы, но вышла другая ошибка
"[RuntimeException]
Changing columns for table "articles" requires Doctrine DBAL; install "doctrine/dba 1"."

Т.е. то о чем Вы пишите. Добавить doctrine/dba 1.

Смею спросить а как правильно установить этот doctrine/dba 1.
Нашел:
"Если вы используете функцию renameColumn в ваших миграциях, то вам надо будет добавить зависимость doctrine/dbal в ваш файл composer.json. Этот пакет больше не входит в Laravel по умолчанию."

Где находится файл composer.json. что за зависимость необходимо добавить? Я так понимаю, что по умолчанию в Laravel сейчас нет doctrine/dba. Может быть внешние ключи можно установить неким более простым способом? Или все таки установить doctrine, но опять же как?

Не в сети

#6 30.03.2017 14:09:35

Re: Ошибка SQLSTATE[42S21]

ещё раз – если не используешь каскадные эффекты, внешние ключи в mysql добавлять не нужно. связи моделей не используют foreign keys никак вообще, и от их наличия или отсутствия не зависят. внешние ключи нужны только в связке с on cascade delete, on cascade update и on cascade set null.

composer.json находится в корне проекта, doctrine/dbal – это не доктрина, это только её DataBase Abstraction Layer, устанавливается командой composer require doctrine/dbal в корне проекта, нужна только для сложных миграций, то есть не всем и не всегда – потому в стандартную установку и не входит

Не в сети

#7 30.03.2017 14:33:57

skiphog
Откуда: Киров, Россия
Сообщений: 26

Re: Ошибка SQLSTATE[42S21]

SZV пишет:

Может быть внешние ключи можно установить неким более простым способом?

Судя по "mySQL 5.7-64" у вас установлен OpenServer? Там есть PhpMyadmin.
Зайдите туда, выберите вашу БД и выполните запрос
Для юзеров

alter table articles add foreign key articles_user_id_foreign (user_id) references users(id)

И для категорий

alter table articles add foreign key articles_category_id_foreign (category_id) references categories(id)

Ну и да. Вам уже написали

constb пишет:

...внешние ключи нужны только в связке с on cascade delete, on cascade update и on cascade set null

Не в сети

#8 30.03.2017 16:21:51

Re: Ошибка SQLSTATE[42S21]

skiphog пишет:
SZV пишет:

Может быть внешние ключи можно установить неким более простым способом?

Судя по "mySQL 5.7-64" у вас установлен OpenServer? Там есть PhpMyadmin.
Зайдите туда, выберите вашу БД и выполните запрос
Для юзеров

alter table articles add foreign key articles_user_id_foreign (user_id) references users(id)

И для категорий

alter table articles add foreign key articles_category_id_foreign (category_id) references categories(id)

Ну и да. Вам уже написали

constb пишет:

...внешние ключи нужны только в связке с on cascade delete, on cascade update и on cascade set null

Благодарю. К таблице articles в индексах прописалась строка articles_user_id_foreign, но по прежнему нет строки  articles_category_id_foreign.
Блин, а есть более простой способ подключения внешних ключей к готовым таблицам?

Не в сети

#9 31.03.2017 04:44:24

Re: Ошибка SQLSTATE[42S21]

SZV, по-моему ты просто не понимаешь что такое внешний ключ в реляционных СУБД. это не поле, а ограничение (constraint). естественно у тебя никакой строки ниоткуда не появится. я третий и последний раз скажу это – тебе не нужен здесь foreign key

Не в сети

Подвал раздела