如何在laravel迁移中更改枚举类型列?

Vin*_* VT 21 migration enums laravel laravel-5.1

我正在使用Laravel 5.1,我有一个名为包的表,具有以下结构:

id              int(11)
weight          decimal(10,2)           
weight_unit     enum('Kg.', 'Gm.')
Run Code Online (Sandbox Code Playgroud)

我想将weight_unit枚举更改为:

weight_unit enum('Grams','Kgs.','Pounds')

为此我创建了以下迁移:

public function up()
{
    Schema::table('packages', function ($table) {
        $table->enum('weight_unit', array('Grams','Kgs.','Pounds'))->nullable()->change();
    });
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行迁移时,我收到一个错误:

Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform  

may not support it.
Run Code Online (Sandbox Code Playgroud)

如何更改此枚举?

Jak*_*ner 24

使用DB::statement方法:

DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,你有一个语法错误.如果你不想重复列名,你必须使用`MODIFY`而不是`CHANGE`. (7认同)
  • 您只能在此解决方案中使用支持 ENUM 类型的数据库,请注意。例如,使用 SQLite 运行测试将会中断。如果不考虑可移植性并且您总是使用 MySQL,那么这可以正常工作。 (4认同)
  • SQLite 不支持语句,因此 PHPUnit 测试将失败! (2认同)

小智 13

我认为 Laravel 10 通过添加对本机列修改的支持来解决这个问题。

https://github.com/laravel/framework/pull/45487

所以从 Laravel 10 开始你可以这样做:

Schema::table('jobs', function (Blueprint $table) {
    $table->enum('type', ['contract', 'permanent', 'partial'])->change();
});
Run Code Online (Sandbox Code Playgroud)

我在新的 Laravel 9.55.0 和 10.0.2 应用程序上尝试了相同的迁移:

laravel-9.52.0.jpg

laravel-10.0.2.jpg

更新:如果您已在 类Schema::useNativeSchemaOperationsIfPossible()的 boot 方法App\Providers\AppServiceProvider或迁移文件中的项目调用方法中安装了“doctrine/dbal”,以便能够使用本机架构操作,如上面的 GitHub 拉取请求中提到的那样。


Ray*_*ter 12

在为修改后的枚举列添加新的枚举值时,这对我有用.

将以下内容添加到up()方法中:

DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds', 'new value') NOT NULL");
Run Code Online (Sandbox Code Playgroud)

然后在该down()方法中,您可以还原所做的更改:

DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds') NOT NULL");
Run Code Online (Sandbox Code Playgroud)

注意:在删除枚举值之前,需要将其更改为将保留的另一个枚举值.


小智 12

$table->enum('level', ['easy', 'hard']);
Run Code Online (Sandbox Code Playgroud)

  • 这会为该列创建一个枚举。这不能用于修改列的现有枚举的值 (2认同)

Alb*_*rto 5

如果您不想丢失数据并使用新值更新它,我想出了这个解决方案:

// Include old and new enum values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Kg.', 'Gm.', 'Grams', 'Kgs', 'Pounds')");
// Replace Kg. with Kgs
Packages::where('weight_unit', 'Kg.')->update(['weight_unit' => 'Kgs']);
// Replace Gm. with Grams
Packages::where('weight_unit', 'Gm.')->update(['weight_unit' => 'Grams']);
// Delete old values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
Run Code Online (Sandbox Code Playgroud)

这样您就可以用新值替换旧值。