【问题标题】:Alter table modify enum in Knex js for Postgresql gives errorAlter table modify enum in Knex js for Postgresql 给出错误
【发布时间】:2023-03-20 03:59:01
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: enums knex.js postgresql-9.5


    【解决方案1】:

    Alter 列不适用于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 从 DB 生成的约束名称。

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

    【讨论】:

    • 感谢@mikael,我更改了约束名称并且它起作用了。
    【解决方案2】:

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

    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 替换为您的约束名称。

    【讨论】:

      【解决方案3】:

      由于alter() 方法不适用于enu/enum 列,我建议删除该列,然后按照您喜欢的方式重新创建它。例如,如果您想更改枚举文本,您可以执行以下操作:

      export async function up(knex: Knex): Promise<void> {
        await knex.schema.alterTable('<table name>', (table) => {
          table.dropColumn('column name');
        });
        await knex.schema.alterTable('<table name>', (table) => {
          table.enu('column name', ['old enum 1', 'old enum 2'])
        });
      }
      
      export async function down(knex: Knex): Promise<void> {
        await knex.schema.alterTable('<table name>', (table) => {
          table.dropColumn('column name');
        });
      
        await knex.schema.alterTable('<table name>', (table) => {
          table.enu('column name', ['new enum 1', 'new enum2'])
        });
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-21
        • 2014-02-24
        • 2019-01-22
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        相关资源
        最近更新 更多