Миграция БД Laravel - ошибка переименования столбца - Запрошено перечисление неизвестного типа базы данных
Я использую Laravel 4.2
. У меня есть следующая библиотека, загруженная в мой composer.json
"doctrine/dbal": "2.4.*",
Я создал следующую миграцию:
class RenameDeliveryNotesColumnOnOrderHeaderTable extends Migration {
public function up()
{
Schema::table('order_header', function(Blueprint $table)
{
$table->renameColumn('delivery_notes', 'packing_notes');
});
}
}
Где delivery_notes
тип столбца равен text
.
Когда я запускаю миграцию, я получаю следующую ошибку:
[Исключение Doctrine\DBAL\dbalexception] Запрошено перечисление неизвестного типа базы данных, Doctrine\DBAL\Платформы\Mysqlplatform может не поддерживать его.
Есть идеи, почему я получаю эту ошибку? Как мне это исправить? Мне нужно переименовать столбец в моей таблице. Есть ли какой-либо альтернативный способ переименования столбца?
7 answers
В документации Laravel говорится, что:
Примечание: Переименование
enum
типов столбцов не поддерживается.
Здесь: https://github.com/laravel/framework/issues/1186
Вы можете найти некоторые обходные пути решения этой проблемы. И поскольку вы сказали, что этот столбец не enum
, взгляните на комментарий @upngo:
"...Проблема заключается в переименовании ЛЮБОГО столбца в таблице, которая имеет
enum
."
Также я нашел эту статью, которая посвящена этой проблеме, и предлагаю вариант, который может вам помочь.
DB::getDoctrineSchemaManager()
->getDatabasePlatform()
->registerDoctrineTypeMapping('enum', 'string');
Это работает для меня на Laravel 5.1
Я столкнулся с этой проблемой в Laravel версии 5.1.19 (LTS). Это актуально и для более ранних версий. Я хотел сообщить вам, как я решил проблему, основываясь на предыдущих комментариях.
Прежде всего, я попробовал следующий код в своем файле миграции:
$table->renameColumn('column_name');
Но после команды php artisan migrate
я получил следующую ошибку:
[Symfony\Компонент\Отладка\Исключение\Исключение Fatalerrorexception] Класс "Доктрина\DBAL\Драйвер\PDOMYSQL\Драйвер" не найден
Как вы знаете, DBAL был удален из ядро laravel, и нам нужно добавить его в composer.json.(Например: "require": {"doctrine/dbal": "2.5.1"}
).
Я установил DBAL как требуется и снова попытался выполнить команду переноса, но получил следующую ошибку:
[Доктрина\DBAL\Исключение DBALEXCEPTION]
Запрошено перечисление неизвестного типа базы данных, Доктрина\DBAL\Платформы\Mysqlplatform может не поддерживать его.
Затем я попробовал следующий необработанный sql в своем файле миграции:
Для up()
:
DB::statement("ALTER TABLE `table_name` CHANGE `old_column_name` `new_column_name` ENUM('first value', 'second_value', ...) DEFAULT 'first_value' AFTER `some_field`");
Для down()
:
DB::statement("ALTER TABLE `table_name` CHANGE `new_column_name` `old_column_name` ENUM('first value', 'second_value', ...) DEFAULT 'first_value' AFTER `some_field`");
И это работает.
P.S. Для переименования других полей в в таблице, содержащей поле перечисления, мы должны использовать ту же схему с необработанным sql, что и в предыдущих комментариях.
Вы можете добавить пользовательский конструктор в миграцию и объяснить Доктрине, что перечисление следует рассматривать как строку.
public function __construct(\Doctrine\DBAL\Migrations\Version $version)
{
parent::__construct($version);
$this->platform->registerDoctrineTypeMapping('enum', 'string');
}
У меня была та же проблема с Laravel 5.1 и PostGres.
Поэтому в основном я использовал DB::statement
для создания перечисления и решения проблемы:
Инструкция DB::("СОЗДАЙТЕ ПОЛЬЗОВАТЕЛЕЙ ТИПА e_ КАК ПЕРЕЧИСЛЕНИЕ ('data1','data2')");
И затем:
Инструкция DB::("ИЗМЕНИТЬ ТАБЛИЦУ пользователи ДОБАВЛЯЮТ СТОЛБЕЦ e_users столбца");
Хотя у первоначального автора были проблемы с Laravel 4, это можно безопасно исправить в Laravel 5, изменив версию doctrine/dbal
в вашем composer.json
по ^2.6
, как это было исправлено в этом PR в выпуске 2.6.0
Обязательно проверьте наличие изменений, нарушающих совместимость в журнале изменений выпуска
Вот ответ для Laravel 5.2.45+ (может работать и в 5.1, еще не тестировался или не проверялся, пожалуйста, дайте мне знать, чтобы я мог обновить этот вопрос.)
Добавьте эту строку в свой метод:
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Что-то вроде этого:
public function up()
{
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Schema::table('users', function (Blueprint $table) {
$table->text('bio')->change();
});
}