framework: [Bug] Schema builder - renameColumn fails on table with enum columns
Example code:
Schema::create('presentations', function($table)
{
...
$table->enum('repeat_unit', array('DAY', 'WEEK', 'MONTH', 'YEAR'))->default('DAY');
...
});
Schema::table('presentations', function($table)
{
$table->renameColumn('created', 'created_at');
});
Result:
[Doctrine\DBAL\DBALException] Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Reactions: 23
- Comments: 82 (24 by maintainers)
Links to this issue
Commits related to this issue
- Fix to ensure we can rename columns in tables with enums See https://github.com/laravel/framework/issues/1186 — committed to flarum/framework by tobyzerner 6 years ago
- Fix migration to use raw statement Necessary due to this five year old issue in the Laravel codebase: https://github.com/laravel/framework/issues/1186 — committed to ProcessMaker/processmaker by ryancooley 5 years ago
- Merge pull request #1186 from dunhamjared/8.x [8.x] Removed unused local variable — committed to Hydrane/tmp-laravel-framework by taylorotwell 3 years ago
Workaround, during development (if there exists no important data): Drop the column and add a new one.
This worked for me in laravel 5.2 with doctrine/dbal@^2.5 . When you have an enum on your table and you want to change any of the columns on the table you will have to:
The docs aren’t correct, they say renaming enum columns isn’t support, but this actually happens when renaming any column on a table that contains an enum column.
It looks like the “workaround” for this is to just tell Doctrine an enum is a string: http://wildlyinaccurate.com/doctrine-2-resolving-unknown-database-type-enum-requested
I’ve attempted to do this in Laravel by doing the following, but the issue still occurs:
I’m not entirely sure how Laravel interacts with Doctrine so I might grabbing the wrong platform instance (or adding it too late?). Any insight on how to make this work inside of Laravel?
3 years later and Doctrine hasn’t fix this issue which is a shame.
Still hitting this issue 3 years later, having to use the manual DB statement solution which is a shame.
This is something I could not believe at first. But thanks to Paul Bill I did it as following
Can someone managing this GitHub repository please summarize the current state of this issue?
My own opinion is that sure, monkey patching isn’t desirable, but it’s quite often necessary in our field. Newcomers to Laravel are hitting this problem in large numbers. This is bad for the reputation of the product.
Yes Doctrine should fix it, but it has been three years. Now it falls on the Laravel framework to create an intuitive development experience for its users.
(PS - this is an amazing framework and thank you everyone for your contributions to it. I’m sure we can find a solution for this simple problem.)
As @shnhrrsn pointed out, the docs are wrong and still haven’t changed (7 months after being reported, and it’s a fairly common issue for anyone new to laravel).
The issue is renaming ANY column on a table that has an enum.
Please reopen issue! Laravel v5.4.25 problem still exists
I think doctrine is gone in 4.1 😃
Gotta say there are some silly comments on this thread.
If you’re not using the framework anymore why are you bothering to write a tirade on here about why it doesn’t work for you?
Also, these are free, open source projects. That means 2 things:
The developers don’t get an immediate financial reward/incentive to help contribute towards ongoing development. Any funds they do get usually barely covers the investment they’ve already made and is likely going towards more big-hitting features that will benefit many more people (you included).
There’s nothing and no one stopping you from writing your own alternative based on DBAL or Laravel that works the way you want it to. Heck you don’t even have to take the time or trouble to share it back with the community. It literally only takes some time and a little effort.
So it really is pointless coming on here just to vent about that thing you want for those occasional projects that need it that clearly many folks can go without.
And it’s a bit childish to slam a perfectly good framework that is working very well in a lot of cases for a lot of people because you have a little issue that’s been around for a few years.
A lot of things have been failing for a lot longer than DBAL hasn’t been able to edit tables with enum columns. I mean my toaster still can’t toast 2 pieces of bread consistently on the same setting. That’s been at least 30 years. Let’s keep some perspective.
I ended up using @ISaidHey 's suggestion, this is my take:
config/database.php
app/Providers/AppServiceProvider.php
I believe it wouldn’t hurt if laravel could parse the
types_mapping
array by default in the migrate command@zschuessler feel free to make a PR to fix the issue if you can do it.
Heck here’s an even more temporary one
This still exists, just downloaded Laravel 5.5.18. I think the bug is bad enough but the misleading error message is worse, given that i’m not even trying to rename the enum column in my table.
[Doctrine\DBAL\DBALException]
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.
For those who are looking for an workaround, I have a better solution. Instead of using
Schema
, use Query Builder and write SQL Query for those rename operations.I don’t get why everyone suggests just register the mapping as string. Wouldn’t that ruin your enum column when you rename another column on the table?
When I tried to use change got same issue on Laravel 5 and doctrine/dbal ~2.5.0. But I solved the problem with using raw query like this:
I see that in Laravel 6 that has been released recently, there is still this non-sense in the documentation.
I think that 1 viable solution for those who have data in their tables would be:
enum_col_2
enum_col
enum_col
enum_col
enum_col_2
toenum_col
enum_col_2
If you come across this comment, I think this will help you.
You must have same question as I and other think about this problem and don’t want to use DB statement. I’m in same boat as you so I search all in google and found solution that I think it is best practise right now. I use Laravel 5.3. Current DBAL hash some update and depend on @henritoivar solution only is not work. DBAL will throw error that you need to define type in DBAL. They need sql processor.
First. Please read all this page. http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/cookbook/mysql-enums.html This is doc that talk about why doctrine don’t implement about enum on it.
Second. I will keep it short. This is my implement.
After you saw these files. You may found it look stupid but this is solution right now. Problem is DBAL don’t receive another attribute so I cannot pass enum values to it.
@peppy if you have a fix in mind you can open a PR.
Hey hey here is my approach:
\Doctrine\DBAL\Types\Type::addType('enum', \Doctrine\DBAL\Types\StringType::class);
Beware this changes the column to varchar! Use your own enum class implementation or the one provided by doctrine: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/cookbook/mysql-enums.html
Either put it into a ServiceProvider or into your migrations or into your bootstrap/app.php Whatever floats your boat I used the following approach:
App/Providers/DatabaseServiceProvider.php
bootstrap/app.php
$app->register(App\Providers\DatabaseServiceProvider::class);
Hope this helps someone and saves precious time I wasted reading thru a lot of discussion…
In the end none of the suggested solutions worked and doctrines error message pointed me into the right direction
FYI in 5.8 you can use something like this:
Schema::registerCustomDoctrineType(Doctrine\DBAL\Types\StringType::class, 'enum', 'ENUM');
Alternatively and for sure the simplest solution is to use a raw statement which preserves your data:
This raw statements can rename the column and add change the types.
Another solution could be to set integers and map those in a config in your code!
In databases it is never a good idea to encode multiple pieces of information in one field because it can’t be indexed and is slower/more complicated to query, and makes life harder for future developers that work on it.
running into the same issue with a json blob on the table 😦
My simple solution was to use raw SQL.
Updated documentation.
not sure why people keep commenting on the laravel version. it is not a laravel problem it is a DBAL problem which is an entirely different package.
Is there a reason this isn’t getting fixed? These kinds of 3-year-still-not-fixed bugs are just insane. I’m pretty sure using
enum
in a table is not a rare case.I too just came into this issue 2 days ago. ENUM is widely used and I can’t, in any way shape or form, understand why someone would think it should not be supported. Nor did I realize this was an issue that clearly causing some issues and has been sat on for over 3 years… However I’ve come across a few resources that could possibly be the fix for this issue!
http://stackoverflow.com/questions/37793349/error-on-php-artisan-migrate-laravel http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/mysql-enums.html
Hopefully one of these are helpful!
I’ve noticed a lot of these issues are specifically related to using the
renameColumn()
method. However, it’s also an issue when usingchange()
(yes, even when the column being changed is not anENUM
).Seems the most convenient way around this (but by no means the best way) is to drop the column and re-create… unless/until Laravel is updated with a work-around or Doctrine gets updated.
Ran into this today. It seems that every call of
Scheme
doing arenameColumn
will create an entirely new DoctrineConnection(). That means we cannot simply do aregisterDoctrineTypeMapping()
globally for enum. So, your options are to either add'enum' => 'string'
directly toDoctrine\DBAL\Platforms\MySqlPlatform
’s initializeDoctrineTypeMappings() or modifyIlluminate\Database\Connection
’s getDoctrineSchemaManager() to look like this:It seems extremely unlikely that Doctrine is going to change, so I can only hope that @taylorotwell might think about adding this change in to Laravel. The database I am using is legacy, but I think I am going to try and move it away from enum.
I’m using Laravel 5.7 with Mariadb and wrote this migration. It worked for me.
@simonhamp there’s no trolling going on in this thread. People are posting because it’s a genuine issue when you cannot run your migrations because Laravel isn’t providing a simple function that could work around the issue like @G3z suggested.
In Illuminate\Database\Connection would it be possible to do something like the following in the getDoctrineConnection() method?
Users would then add a ‘mapping_types’ => [] parameter to their database settings in config/database.php, i.e.:
Just trying to get some insight if that might break anything before I do a PR. Have done the changes locally on 5.3 and it allows me to update columns on tables with the json type. Thanks for the awesome framework, been a joy to work with so far.
For who found this problem, next time I think use INT field is better solution. After I try to think why DBAL don’t do it. If I’m in same boat, I will do same too because their design pattern don’t allow them to implement ENUM.
If I can forecast or see future, this problem will stay same in 4 or 5 years. LOL
GL HF.
PS. Currently I like INT field better because I can use bitwise to store more than single value in one field.
Couldn’t laravel leave in this functionality but throw an exception if Doctrine is not loaded? I personally do not need it so I would prefer to not to include doctrine for this one feature. Another suggestion is why not just extend schema to add column renaming which uses doctrine if you need it? It seems like some others would be interested and could help maintain the package?
Has anyone had any luck with a workaround on this? Causing some major headaches.