更改表修改枚举在Knex js中为Postgresql提供错误

时间:2017-07-25 09:39:35

标签: enums knex.js postgresql-9.5

我正在使用knex js和postgresql数据库。我使用迁移文件来创建表knex migrate:make create_car_table。在这里我添加了一列fuel_type。 table.enu('fuel_type', ['PETROL', 'DIESEL', 'CNG'])

现在我需要更改表格,我需要这些枚举值['HYBRID', 'ELECTRIC', 'PETROL', 'DIESEL']

我使用knex migrate:make alter_car_table创建了另一个迁移文件,并添加了以下代码

exports.up = function(knex, Promise) {
    return knex.schema.alterTable('car', function (table) {
        table.enu('fuel_type', ['HYBRID', 'ELECTRIC', 'PETROL', 'DIESEL']).alter();
    });
};

exports.down = function(knex, Promise) {
    return knex.schema.alterTable('car', function (table) {
        table.enu('fuel_type', ['PETROL', 'DIESEL', 'CNG']).alter();
    });
};

当我运行knex migrate:latest时,我收到以下错误。

Knex:warning - migrations failed with error: alter table "car" alter column "fuel_type" type text check ("fuel_type" in ('HYBRID', 'ELECTRIC', 'PETROL', 'DIESEL')) using ("fuel_type"::text check ("fuel_type" in ('HYBRID', 'ELECTRIC', 'PETROL', 'DIESEL'))) - syntax error at or near "check"

我已经提到Knex Js了。

2 个答案:

答案 0 :(得分:9)

更改列不适用于knex 0.13.0中的枚举类型。

此外,枚举也被实现为检查约束,因此要更改它,您需要重新创建。

这样的事情:

exports.up = function(knex, Promise) {
  return knex.schema.raw(`
    ALTER TABLE "car"
    DROP CONSTRAINT "car_fuel_type_check",
    ADD CONSTRAINT "car_fuel_type_check" 
    CHECK (fuel_type IN ('HYBRID', 'ELECTRIC', 'PETROL', 'DIESEL'))
  `);
};

exports.down = function(knex, Promise) { ... };

您可能需要检查最初由数据库中的knex生成的约束名称。

目前knex.schema.raw是修改枚举的唯一方法。

答案 1 :(得分:0)

您首先需要删除现有约束,并使用新值创建一个新约束。 下面的代码示例应该会有所帮助。

exports.up = function(knex, Promise) {
  return knex.schema.raw(`
    ALTER TABLE "car" DROP CONSTRAINT "car_fuel_type_check";
    ALTER TABLE "car" ADD CONSTRAINT "car_fuel_type_check" CHECK (fuel_type IN ('HYBRID'::text, 'ELECTRIC'::text, 'PETROL'::text, 'DIESEL'::text))
  `);
};

// The reverse migration is similar
exports.down = function(knex, Promise) {
  return knex.schema.raw(`
    ALTER TABLE "car" DROP CONSTRAINT "car_fuel_type_check";
    ALTER TABLE "car" ADD CONSTRAINT "car_fuel_type_check" CHECK (fuel_type IN ('PETROL'::text, 'DIESEL'::text, 'CNG'::text));
  `);
};

我假设您的约束名称为car_fuel_type_check。如果不是,则应使用约束名称替换car_fuel_type_check