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

ckx4rj1h  于 2023-02-20  发布在  其他
关注(0)|答案(9)|浏览(122)

我使用的是Laravel 5.1,我有一个名为packages的表,其结构如下:

id              int(11)
weight          decimal(10,2)           
weight_unit     enum('Kg.', 'Gm.')

我想将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();
    });
}

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

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

may not support it.

如何更改此枚举?

tkclm6bt

tkclm6bt1#

使用DB::statement方法:

DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
l3zydbqr

l3zydbqr2#

当向修改后的枚举列添加新的枚举值时,这对我很有效。
将以下内容添加到up()方法中:

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

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

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

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

zdwk9cvp

zdwk9cvp3#

$table->enum('level', ['easy', 'hard']);
rjee0c15

rjee0c154#

您可以在迁移中添加自定义构造函数,并向Doctrine解释enum应该像字符串一样处理。

public function __construct(\Doctrine\DBAL\Migrations\Version $version)
{
    parent::__construct($version);

    $this->platform->registerDoctrineTypeMapping('enum', 'string');
}
kyxcudwk

kyxcudwk5#

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

// 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')");

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

ltqd579y

ltqd579y6#

在change()调用之前添加以下内容:

DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
pxyaymoc

pxyaymoc7#

我认为这是固定的Laravel 10增加了支持原生列修改。
https://github.com/laravel/framework/pull/45487
因此,从Laravel 10您可以这样做:

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

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

zbdgwd5y

zbdgwd5y8#

我能够通过删除和添加约束来解决这个问题。这确保了我现有的数据也是完整的。

DB::statement("ALTER TABLE purchases DROP CONSTRAINT purchases_ref_check");
$types = ['single', 'monthly', 'biannual', 'amount', 'other'];
$result = join( ', ', array_map(function( $value ){ return sprintf("'%s'::character varying", $value); }, $types) );
DB::statement("ALTER TABLE purchases add CONSTRAINT purchases_ref_check CHECK (ref::text = ANY (ARRAY[$result]::text[]))");
5anewei6

5anewei69#

使用默认值。将此添加到up()中:

\DB::statement("ALTER TABLE `patient_appointments` CHANGE `status` `status` ENUM('pending','wait','approved', 'consulted') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending';");

相关问题