使用 PostgreSQL 更新 Laravel 迁移中的枚举列
Update enum column in Laravel migration using PostgreSQL
根据 this answer,如果我想更新 MySQL 中的 enum
,我必须 运行 原始查询。但是对于 PostgreSQL,我不能使用这个查询,Laravel 中 PostgreSQL 的枚举类型看起来很奇怪。
有什么方法可以更新 postgreSQL 迁移中的枚举吗?
Laravel 在 character varying
上对 enum
使用约束。
假设有一个 table mytable
和一个枚举列 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[]))');
});
解决了问题,希望对你有帮助!
扩展@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']);
请注意,如果要删除 table 中使用的约束,则需要将所有实例重命名为列表中的名称,或者删除 [=19] 之前的所有实例=] 这个函数
根据 this answer,如果我想更新 MySQL 中的 enum
,我必须 运行 原始查询。但是对于 PostgreSQL,我不能使用这个查询,Laravel 中 PostgreSQL 的枚举类型看起来很奇怪。
有什么方法可以更新 postgreSQL 迁移中的枚举吗?
Laravel 在 character varying
上对 enum
使用约束。
假设有一个 table mytable
和一个枚举列 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[]))');
});
解决了问题,希望对你有帮助!
扩展@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']);
请注意,如果要删除 table 中使用的约束,则需要将所有实例重命名为列表中的名称,或者删除 [=19] 之前的所有实例=] 这个函数