4

According to this answer, I have to run a raw query if I want to update an enum in MySQL. But with PostgreSQL, I can't use this query, and enum type for PostgreSQL in Laravel seems strange.

Is there any way to update enum in a migration for postgreSQL ?

4

2 回答 2

10

Laravel 对character varyingfor使用约束enum

假设有一个mytable带有 enum column的表status,我们必须删除约束(名为tablename _ columnname _ check)然后将其添加到迁移中,如下所示:

DB::transaction(function () {
    DB::statement('ALTER TABLE mytable DROP CONSTRAINT mytable_status_check;');
    DB::statement('ALTER TABLE mytable ADD CONSTRAINT mytable_status_check CHECK (status::TEXT = ANY (ARRAY[\'pending\'::CHARACTER VARYING, \'accepted\'::CHARACTER VARYING, \'canceled\'::CHARACTER VARYING]::TEXT[]))');
});

它解决了问题,希望它可以帮助!

于 2015-06-17T07:18:02.590 回答
4

要扩展@rap-2-h 的答案 - 这是您可以使用的通用方法:

/**
 * Alter an enum field constraints
 * @param $table
 * @param $field
 * @param array $options
 */
protected function alterEnum($table, $field, array $options) {

    $check = "${table}_${field}_check";

    $enumList = [];

    foreach($options as $option) {
        $enumList[] = sprintf("'%s'::CHARACTER VARYING", $option);
    }

    $enumString = implode(", ", $enumList);

    DB::transaction(function () use ($table, $field, $check, $options, $enumString) {
        DB::statement(sprintf('ALTER TABLE %s DROP CONSTRAINT %s;', $table, $check));
        DB::statement(sprintf('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s::TEXT = ANY (ARRAY[%s]::TEXT[]))', $table, $check, $field, $enumString));
    });

}

示例用法:

$this->alterEnum('mytable', 'status', ['pending', 'accepted', 'canceled']);

请注意,如果您要删除表中使用的约束,则需要将所有实例重命名为列表中的内容,或者在运行此函数之前删除所有实例

于 2016-03-24T10:57:39.043 回答