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.
This would be a Doctrine DBAL issue. We may just need to document that this is the case until (and if) they implement something upstream.
Updated documentation.
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:
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');
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?
Has anyone had any luck with a workaround on this? Causing some major headaches.
Workaround, during development (if there exists no important data): Drop the column and add a new one.
public function up()
{
Schema::table('users', function(Blueprint $table)
{
$table->dropColumn('name');
});
Schema::table('users', function(Blueprint $table)
{
$table->text('username');
});
}
Any resolution to this issue?
+1 just ran into this issue. I know it is a Doctrine DBAL issue but I wonder if there is something Laravel can do to provide a workaround.
I think doctrine is gone in 4.1 :-)
On 22 Nov 2013, at 2:01 am, Eric Junker [email protected] wrote:
+1 just ran into this issue. I know it is a Doctrine DBAL issue but I wonder if there is something Laravel can do to provide a workaround.
—
Reply to this email directly or view it on GitHub.
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?
I have a feeling it's been replaced using DB commands in 4.1
On 22 Nov 2013, at 6:27 am, Patrick Heeney [email protected] wrote:
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?
—
Reply to this email directly or view it on GitHub.
Yeah it's still in 4.1
https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Schema/Blueprint.php
On 22 Nov 2013, at 6:27 am, Patrick Heeney [email protected] wrote:
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?
—
Reply to this email directly or view it on GitHub.
@patrickheeney
Couldn't laravel leave in this functionality but throw an exception if Doctrine is not loaded?
It has been moved to suggest https://github.com/laravel/framework/blob/master/composer.json#L90. If anyone need it, you just update your app composer.json
to include it and it would be available.
@crynobone I thought I saw something like that. Thanks for the information.
Ran into this today. It seems that every call of Scheme
doing a renameColumn
will create an entirely new DoctrineConnection(). That means we cannot simply do a registerDoctrineTypeMapping()
globally for enum. So, your options are to either add 'enum' => 'string'
directly to Doctrine\DBAL\Platforms\MySqlPlatform
's initializeDoctrineTypeMappings() or modify Illuminate\Database\Connection
's getDoctrineSchemaManager() to look like this:
public function getDoctrineSchemaManager()
{
$schema = $this->getDoctrineDriver()->getSchemaManager($this->getDoctrineConnection());
$schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
return $schema;
}
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 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?
Ran a test with an additional update and it seems to do nothing to the enum() in MySQL. Doctrine seems to be using these type mappings primarily in _getPortableTableColumnDefinition
. You likely know Doctrine a bit better than I, but with this I can at least get my migrations working.
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.
https://github.com/laravel/framework/pull/2133
doctrine thus renaming columns has been removed from laravel core so this probably isn't going to get fixed.
Found another interesting case, if you create a migration which converts enums to strings (raw queries) and then use Schema to rename columns in that table (which now has no enums) then you can run this migration back and forth using artisan migrate(:rollback) but if you run the migration in pretend mode artisan migrate --pretend then the doctrine error above will come up. I assume it's because it ignores the first query changing the enums, then evaluates what the second query would do (rename a column on a table that still has enums!) and complains.
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.
Is there any improvement in this issue? I'm having the same problem here. :(
I'm new to Laravel and I'm currently scratching my head over, what I presume, is the same issue. In my case the datatype it's complaining about is a 'point' which isn't even the field I'm trying to rename.
@kebian the docs are still incorrect, reading my last comments you'll see that you can't rename any columns on tables which contain enums
@upngo That does indeed seem to be the case, however my table doesn't contain any enum columns but does contain a geospatial "point" field. Perhaps the bug is with any non-standard field types.
I've noticed a lot of these issues are specifically related to using the renameColumn()
method. However, it's also an issue when using change()
(yes, even when the column being changed is not an ENUM
).
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.
@simonhamp alternative to dropping (and losing all rows) would be to just use a raw query in whatever db language you're using
@kebian yes this is the case, if you see the comment at the top of the page from @shnhrrsn it's that DBAL doesnt know enum and probably not point either, the work around was to tell mysql it's just a string.
This issue isn't going anywhere though -> unsubscribing.
@upngo good point. Will do that in future
Hit this issue today on Laravel 5 and dbal 2.5.1, can't call change on any column if my table has any enum or point columns in it.
This is something I could not believe at first. But thanks to Paul Bill I did it as following
public function up()
{
Schema::table('projects', function(Blueprint $table)
{
DB::statement('ALTER TABLE projects CHANGE slug url VARCHAR(200)');
});
}
public function down()
{
Schema::table('projects', function(Blueprint $table)
{
DB::statement('ALTER TABLE projects CHANGE url slug VARCHAR(200)');
});
}
Follow up to this problem as I had it too...
I figured out fairly simple solution at least to my case.
As @malcolmhall said, it was not letting me update ANY columns in my table if that table had an enum in it.
If I moved the renaming unto it's own function instead of trying to include it with the rest of my migration it worked. For example....
Changed A Migration Like This
public function up()
{
Schema::table('mytable', function(Blueprint $table) {
$table->dropColumn('randomColumn');
$table->string('newColumn', 25)->after('id');
$table->renameColumn('oldColumnName', 'newColumnName');
});
}
To this
public function up()
{
Schema::table('mytable', function(Blueprint $table) {
$table->dropColumn('randomColumn');
$table->string('newColumn', 25)->after('id');
});
Schema::table('mytable', function(Blueprint $table) {
$table->renameColumn('oldColumnName', 'newColumnName');
});
}
By moving the renaming of columns to it's own function it seemed to work. The crazy part is NONE of the fields in my example are enum fields, but since the table contains enum fields I was getting this error.
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:
DB::statement("ALTER TABLE table_name MODIFY COLUMN column_name ENUM('Here','is','choices')");
I've fixed this for hook with a pretty ugly workaround: https://github.com/doubleleft/hook/blob/2ffde1352649513919b51bb591f0668f70a37925/src/Database/Schema/Builder.php#L397-L435
Basically I'm creating a new class extending the EnumType with the allowed options for the migration, and registering it into Doctrine.
Hope it helps!
Still hitting this issue 3 years later, having to use the manual DB statement solution which is a shame.
3 years later and Doctrine hasn't fix this issue which is a shame.
My simple solution was to use raw SQL.
public function up()
{
DB::statement('ALTER TABLE kois ALTER doitsu SET DEFAULT 0');
DB::statement('ALTER TABLE kois ALTER male SET DEFAULT 0');
}
running into the same issue with a json blob on the table :(
still no fix...
@taylorotwell
Just to clarify @reedmaniac 's path, I changed it here: vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
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!
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.
@peppy if you have a fix in mind you can open a PR.
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:
public function up()
{
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Schema::table('jobs', function(Blueprint $table)
{
$table->decimal('latitude', 10, 6)->nullable()->change();
});
}
@henritoivar well this solved my issue! what a crazy hack.
@crynobone Can you explain why you feel Doctrine should fix this? Laravel's Blueprint class offers both a enum()
and a renameColumn()
method, yet they cannot be used in combination.
Can you explain why you feel Doctrine should fix this?
My response is to response to "Still hitting this issue 3 years later, having to use the manual DB statement solution which is a shame.", Don't just put the blame on Laravel when it's been 3 years and Doctrine still hasn't solved it.
Besides that, monkey-patching is never a good solution (which was questioned by Taylor), and Taylor himself mention this at the very first reply.
renameColumn()
highly depends on Doctrine, enum()
doesn't.
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.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Doctrine\DBAL\Types\Type;
class AlterCartCustomersMakeGenderNullable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Type::addType('enum', \Extended\Doctrine\DBAL\Types\GenderEnumType::class);
Schema::table('cart_customers', function(Blueprint $table) {
// add nullable
// must call change to tell we change field attribute
$table->enum('gender', ['male', 'female'])->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Type::addType('enum', \Extended\Doctrine\DBAL\Types\GenderEnumType::class);
Schema::table('cart_customers', function(Blueprint $table) {
// revert nullable
$table->enum('gender', ['male', 'female'])->nullable(false)->change();
});
}
}
<?php
namespace Extended\Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class EnumType extends Type
{
protected $name;
protected $values = array();
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
$values = array_map(function($val) { return "'".$val."'"; }, $this->values);
return "ENUM(".implode(", ", $values).")";
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (!in_array($value, $this->values)) {
throw new \InvalidArgumentException("Invalid '".$this->name."' value.");
}
return $value;
}
public function getName()
{
return $this->name;
}
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}
<?php
namespace Extended\Doctrine\DBAL\Types;
class GenderEnumType extends EnumType
{
protected $values = array('male', 'female');
}
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.
Still not solved ?
Oups I have to switch from ENUM to int with a default value set to 0
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.)
@zschuessler feel free to make a PR to fix the issue if you can do it.
wow! I didn't knew that its an 3 years old issue until i faced the issue myself.
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.
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.
@taylorotwell does this issue still exist?
@jycr753 yes.
In Illuminate\Database\Connection would it be possible to do something like the following in the getDoctrineConnection() method?
$this->doctrineConnection = new DoctrineConnection($data, $driver);
// New code here
if(!is_null($this->getConfig('mapping_types'))) {
$dbPlatform = $this->doctrineConnection->getSchemaManager()->getDatabasePlatform();
foreach($this->getConfig('mapping_types') as $dbType => $doctrineType) {
$dbPlatform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
}
Users would then add a 'mapping_types' => [] parameter to their database settings in config/database.php, i.e.:
'mapping_types' => [
'enum' => 'string',
'json' => 'json_array',
]
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.
OK So I was too lazy to figure out where in my local code to permanently put the code snippet from @johndslone, but what I did discover is you can put a modified version of it at the top of a specific migration file and it will work.
$connection = DB::connection();
$doctrineConnection = $connection->getDoctrineConnection();
// New code here
if (!is_null($connection->getConfig('mapping_types'))) {
$dbPlatform = $doctrineConnection->getSchemaManager()->getDatabasePlatform();
foreach ($connection->getConfig('mapping_types') as $dbType => $doctrineType) {
$dbPlatform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
}
and 1 additional comment, you have to put the mapping_types
array in the specific connection entry of config/database.php
not just as a new top level entry (It wasn't clear to me on first try).
Heck here's an even more temporary one
$map = [
'enum' => 'string',
];
$connection = DB::connection();
$doctrineConnection = $connection->getDoctrineConnection();
// New code here
$dbPlatform = $doctrineConnection->getSchemaManager()->getDatabasePlatform();
foreach ($map as $dbType => $doctrineType) {
$dbPlatform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
Please reopen issue!
Laravel v5.4.25
problem still exists
@ISaidHey Yeah, all that code comes from the workarounds mentioned earlier in the thread. Was just integrating it to a bit more 'permanent' method that would work out of the box. I tend to just use ALTER TABLE statements in my own migrations that involve changes on tables, but I can understand the desire from users to still be able to write migrations using the tools in the documentation.
It creates a bit of a mental disconnect when you can $table->json() add a column, but would be unable to use any change() commands later on because of it. [Not that it's Laravel's fault, since it's an issue with the underlying dbal library]
(The files you would need to edit are in the vendor/src directory - it's just a proof of concept so I could reinstall the original composer files once I was done playing with it)
Its sad that issues like this still plague Laravel.
I hit a similar issue while trying to update columns with a postgis geometry while installing Voyager, there's a workaround described here for laravel-generator although I haven't managed to make it work yet.
I ended up using @ISaidHey 's suggestion, this is my take:
config/database.php
//....
'types_mapping' => [
'ltree' => 'string',
],
app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
// add DBAL Types
$this->addDBALTypes();
}
public function addDBALTypes()
{
$connection = DB::connection();
if (App::runningInConsole()) {
//workaround for php artisan migrate --database=
if (isset($_SERVER['argv'][2]) && strpos($_SERVER['argv'][2], '--database=') !== false) {
$connection = DB::connection(str_replace('--database=', '', $_SERVER['argv'][2]));
}
}
$doctrineConnection = $connection->getDoctrineConnection();
$dbPlatform = $doctrineConnection->getSchemaManager()->getDatabasePlatform();
foreach (config('database.types_mapping', []) as $dbType => $doctrineType) {
$dbPlatform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
}
}
I believe it wouldn't hurt if laravel could parse the types_mapping
array by default in the migrate command
@henritoivar thanks a lot!
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.
Still an issue in 5.5.24. Trying to rename a integer column where the table contains enum.
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.
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.
@itsmill3rtime likely because they've only encountered it in Laravel and people expect limitations to be lifted as framework versions increase over time.
Regardless, it appears the DBAL may never support this, as explained in their docs. FWIW, that link does document some workarounds.
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 see no harm in these discussion threads, personally.
Is this not a good gauge of how many people are potentially relying on this feature from a framework that is otherwise "working very well in a lot of cases"?
As a repository maintainer or potential contributor, it would let me know that maybe I should consider reopening the issue with the possibility of a localised workaround, even if my own project wasn't the one at fault.
Actually not only ENUM not working in migrations, you also cannot use SET, MEDIUMBLOB, LONGBLOB, etc. Thus out the box standard migrations are unuseful in real big projects, unfortunately.
Another solution (with own cons of course) - you can use MySQL Workbench to create migration.sql
and run it inside laravel migrations, but you need split SQL file into single queries (jdorn/sql-formatter can do that, but this package a little outdated) or PDO will fail silently.
@peppy As an _unpaid_ repository maintainer or potential contributor, are you more or less likely to do so if you happen to read the occasional troll comment on a closed issue OR if you can see a clear and definitive trend by way of hundreds of comments, votes., issues, blog posts, tweets?
There’s no such justification that this issue should be given that kind of attention in this case from what I can see.
@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.
@adriennn it looks like the particular comment I was responding to has been removed. Clearly some people _are_ using this thread as an opportunity to have a dig at Laravel, even personally "attacking" the maintainers. That's not only unfair, completely unnecessary and uncalled for, it's utterly stupid.
I agree, this is an issue that I would like to see fixed. I have faced it and it catches me out on those odd occasions, but there's no need to lose one's rag and start attacking people over it.
The fact is that there are ways around it and it's not a major issue afflicting thousands of developers on a daily basis, so just being realistic, I can see why other issues would take priority :)
@adriennn, this simple function is not a solution, because it fixes only "Unknown database type enum requested" message, but change()
migration will not works and you still needed Schema::getConnection()->statement(ALTER TABLE ...)
. So this is more complicated bug :(
@simonhamp roger, didn't see that post.
@LastDragon-ru well if it's a more complicated issue, it proves my above point, I ended up adding 'geom' to the conversion list suggested in that fix and I think/hope it has fixed my problem... let's see for how long...
OP is now working with PHP7.1 and DBAL >= 2.7
I'm using Laravel 5.7 with Mariadb and wrote this migration. It worked for me.
public function up()
{
$options = implode("','", MediationStatus::getValues());
$defaulf = MediationStatus::Opened;
$raw_sql = "ALTER TABLE mediation.mediations
MODIFY COLUMN status ENUM('{$options}')
DEFAULT '{$defaulf}' NOT NULL";
DB::statement($raw_sql);
}
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
<?php
namespace App\Providers;
use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Types\Type;
use Illuminate\Support\ServiceProvider;
class DatabaseServiceProvider extends ServiceProvider
{
public function register()
{
Type::addType('enum', StringType::class);
}
}
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:
DB::statement("ALTER TABLE `table` CHANGE `from` `to` ENUM('item1', 'item2') default NULL;");
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!
Anyone using @pinkal-vansia's solution of writing alter statements, keep in mind your field length. Unless you've overwritten it, the default string length is 255 characters. If you are renaming a string field, be sure to double check that you're not truncating some data or unexpectedly altering a field.
If you have a look at the Blueprint string function it either accepts the length in the second parameter or uses Illuminate\Database\Schema\Builder::$defaultStringLength
, which is currently set to 255. You can either use that number in your migrations or simply alter the previously pasted statement like so:
public function up()
{
Schema::table('projects', function(Blueprint $table)
{
DB::statement('ALTER TABLE projects CHANGE slug url VARCHAR(255)');
});
}
public function down()
{
Schema::table('projects', function(Blueprint $table)
{
DB::statement('ALTER TABLE projects CHANGE url slug VARCHAR(255)');
});
}
I ended up using @ISaidHey 's suggestion, this is my take:
config/database.php
//.... 'types_mapping' => [ 'ltree' => 'string', ],
app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider { public function boot() { // add DBAL Types $this->addDBALTypes(); } public function addDBALTypes() { $connection = DB::connection(); if (App::runningInConsole()) { //workaround for php artisan migrate --database= if (isset($_SERVER['argv'][2]) && strpos($_SERVER['argv'][2], '--database=') !== false) { $connection = DB::connection(str_replace('--database=', '', $_SERVER['argv'][2])); } } $doctrineConnection = $connection->getDoctrineConnection(); $dbPlatform = $doctrineConnection->getSchemaManager()->getDatabasePlatform(); foreach (config('database.types_mapping', []) as $dbType => $doctrineType) { $dbPlatform->registerDoctrineTypeMapping($dbType, $doctrineType); } } }
I believe it wouldn't hurt if laravel could parse the
types_mapping
array by default in the migrate command
Thank you very much, this solution worked perfectly.
I'm working with Laravel 5.8. and I was trying to generate an automatic model from a table with enum fields (https://github.com/krlove/eloquent-model-generator)
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
to enum_col
enum_col_2
Most helpful comment
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: