この回答によるとenum
、MySQL で更新する場合は、生のクエリを実行する必要があります。しかしPostgreSQLではこのクエリが使えず、LaravelでのPostgreSQLのenum型がおかしい。
postgreSQL の移行で enum を更新する方法はありますか?
この回答によるとenum
、MySQL で更新する場合は、生のクエリを実行する必要があります。しかしPostgreSQLではこのクエリが使えず、LaravelでのPostgreSQLのenum型がおかしい。
postgreSQL の移行で enum を更新する方法はありますか?
Laravel はcharacter varying
for の制約を使用します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[]))');
});
それは問題を解決します。
@ 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']);
テーブルで使用されている制約を削除する場合は、この関数を実行する前に、すべてのインスタンスの名前をリストにある名前に変更するか、すべてのインスタンスを削除する必要があることに注意してください。