可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
While running php artisan migrate, I got the following error
[Doctrine\DBAL\DBALException]
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.
How to resolve this issue.
Code:
public function up() {
Schema::table('blogs', function (Blueprint $table) {
$table->string('wordpress_id')->nullable();
$table->string('google_blog_id')->nullable()->change();
});
}
回答1:
The official Laravel 5.1 documentation states:
Note: Renaming columns in a table with a enum column is not currently supported.
It doesn't matter if you're trying to change another column, if the table contains a enum
anywhere it won't work. It's a Doctrine DBAL issue.
As a workaround you could either drop the column and add a new one (column data will be lost):
public function up()
{
Schema::table('users', function(Blueprint $table)
{
$table->dropColumn('name');
});
Schema::table('users', function(Blueprint $table)
{
$table->text('username');
});
}
or use a DB statement:
public function up()
{
DB::statement('ALTER TABLE projects CHANGE slug url VARCHAR(200)');
}
public function down()
{
DB::statement('ALTER TABLE projects CHANGE url slug VARCHAR(200)');
}
Source: https://github.com/laravel/framework/issues/1186
回答2:
It is a known issue as stated in Laravel 5.1 documentation.
Note: Renaming columns in a table with a enum
column is not currently supported.
It happens when you have a enum
column in your database table. Whether you are trying to rename another column, or change another column to nullable
, this bug will appear. It's an issue with Doctrine\DBAL
.
An easy fix for this is to just add this constructor method in your database migration file.
public function __construct()
{
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}
This will map all the ENUM
columns to VARCHAR()
, and the column will accept any string.
This worked for me on Laravel 5.1 and Laravel 5.3. I hope this bug can be fixed soon.
Credit to @Gmatkowski's answer at https://stackoverflow.com/a/32860409/1193201
回答3:
A real dirty solution, that gets the job done none the less would be to
update Doctrine/DBAL/Schema/MySqlSchemaManager.php
by ading these lines just above line 113
$this->_platform->registerDoctrineTypeMapping('enum', 'string');
$type = $this->_platform->getDoctrineTypeMapping($dbType);
Beware that updating vendor files directly is not advisable because in the event the vonder chooses to update the plugin, you changes could be overwritten
回答4:
I get rid of this problem by creating a new Migration Class and making my migrations extending from it. There are multiple ways to make more "standard" but this is just a very simple case which works perfectly for me.
use Doctrine\DBAL\Types\{StringType, Type};
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\{DB, Log};
/**
* Class ExtendedMigration
* Use it when the involved table(s) has enum type column(s)
*/
class ExtendedMigration extends Migration
{
/**
* ExtendedMigration constructor.
* Handle Laravel Issue related with modifying tables with enum columns
*/
public function __construct()
{
try {
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Type::addType('enum', StringType::class);
} catch (\Exception $exception) {
Log::info($exception->getMessage());
}
}
}
Then as explained before just extend your migration from it
class SampleMigration extends ExtendedMigration
{
public function up()
{
Schema::create('invitations', function (Blueprint $table) {
...
$table->enum('status', ['sent', 'consumed', 'expired'])->default('sent');
...
});
}
public function down()
{
Schema::dropIfExists('invitations');
}
}