'Laravel 5.1 Unknown database type enum requested
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();
});
}
Solution 1:[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)');
}
Solution 2:[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
Solution 3:[3]
I get rid of this problem by creating a new Migration Class and making my migrations extending from it. Maybe there are multiple ways to make it more "standard" but this is just a very simple case which works perfectly for our team.
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 {
Type::hasType('enum') ?: Type::addType('enum', StringType::class);
Type::hasType('timestamp') ?: Type::addType('timestamp', DateTimeType::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');
}
}
Solution 4:[4]
You should not use enum at all. Even with laravel 5.8, problem is not resolved.
Thank's to everyone who reminded that
The official Laravel 5.1 documentation states:
Note: Renaming columns in a table with a enum column is not currently supported.
Plus you will have the same problem when adding available options into enum
column declaration.
It brings me to a conclusion that You should use enum with care. or even You should not use enum at all.
I cannot vote up any answer that offer to replace enum with string. NO, you need to create a lookup table and replace enum with unsignedInteger
as a foreign key
.
It is a lot of work and you'll be upset doing it without previous unit-test coverage, but this is a right solution.
You may be even fired for doing this correctly, because it is taking too long, but, don't worry, you'll find a better job. :)
Here is an example of how difficult would it be adding available options into enum
column declaration
say you have this:
Schema::create('blogs', function (Blueprint $table) {
$table->enum('type', [BlogType::KEY_PAYMENTS]);
$table->index(['type', 'created_at']);
...
and you need to make more types available
public function up(): void
{
Schema::table('blogs', function (Blueprint $table) {
$table->dropIndex(['type', 'created_at']);
$table->enum('type_tmp', [
BlogType::KEY_PAYMENTS,
BlogType::KEY_CATS,
BlogType::KEY_DOGS,
])->after('type');
});
DB::statement('update `blogs` as te set te.`type_tmp` = te.`type` ');
Schema::table('blogs', function (Blueprint $table) {
$table->dropColumn('type');
});
Schema::table('blogs', function (Blueprint $table) {
$table->enum('type', [
BlogType::KEY_PAYMENTS,
BlogType::KEY_CATS,
BlogType::KEY_DOGS,
])->after('type_tmp');
});
DB::statement('update `blogs` as te set te.`type` = te.`type_tmp` ');
Schema::table('blogs', function (Blueprint $table) {
$table->dropColumn('type_tmp');
$table->index(['type', 'created_at']);
});
}
Solution 5:[5]
Laravel: 5.8, 6, 7, 8
use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Types\Type;
use Illuminate\Support\Facades\DB;
public function __construct()
{
if (! Type::hasType('enum')) {
Type::addType('enum', StringType::class);
}
// For point types
// DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('point', 'string');
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
}
Solution 6:[6]
You can either use the above suggestions or can add the below code to your migration file...
public function up()
{
DB::connection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Schema::table('<YOUR_TABLE>', function (Blueprint $table) {
//YOUR CHANGES HERE
}
}
Solution 7:[7]
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
Solution 8:[8]
I think the easiest way to fix this issue is adding a mapping type to doctrine.yaml if applicable so that enum will be treated as string.
doctrine:
dbal:
#other configuration
mapping_types:
enum: string
Solution 9:[9]
If you ever run into the error below on a Doctrine with Laminas setup. Find the source of the enum column because my source code contains nothing like it.
Unknown database type enum requested
It was a table schema that phpMyAdmin created in the database that Doctrine wanted to match/sync with my schema definition. And it couldn’t find the enum column contained in the phpMyAdmin schema.
I solved it by moving the pma_
tables to a different database.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jonathan |
Solution 2 | Community |
Solution 3 | |
Solution 4 | |
Solution 5 | |
Solution 6 | Ajjay Arora |
Solution 7 | Cengkuru Michael |
Solution 8 | simsek |
Solution 9 | Karl Hill |