在knex迁移中更新枚举列类型

时间:2016-09-27 00:31:58

标签: javascript enums migration knex.js

我希望编写一个迁移字符串,以便为枚举列类型添加新字符串。我尝试将gamma添加到service列。

我尝试使用下面的代码。这会发生冲突,因为表和列已经存在。

const table = 'user_associations'

export function up (knex, Promise) {
  return knex.schema.table(table, function (table) {
    table.enu('service', ['alpha', 'beta', 'gamma']).notNullable()
  })
}

export function down (knex, Promise) {
  return knex.schema.table(table, function (table) {
    table.enu('service', ['alpha', 'beta']).notNullable()
  })
}

3 个答案:

答案 0 :(得分:2)

const tableName = 'user_associations'

export function up (knex, Promise) {
  let existRows;
  return knex.select()
  .from(tableName)
  .then((rows) => {
    existRows = rows
    return knex.schema.table(tableName, (table) => table.dropColumn('service'))
  })
  .then(() => knex.schema.table(tableName, (table) => table.enu('service', ['alpha', 'beta', 'gamma']).notNullable().default('alpha')))
  .then(() => {
    return Promise.all(existRows.map((row) => {
      return knex(tableName)
      .update({ service: row.service })
      .where('id', row.id)
    }))
  })
}

export default down(kenx, Promise) {
  let existRows;
  return kenx.select()
  .from(tableName)
  .then((rows) => {
    existRows = rows
    return knex.schema.table(tableName, (table) => table.dropColumn('service'))
  })
  .then(() => knex.schema.table(tableName, (table) => table.enu('service', ['alpha', 'beta']).notNullable().default('alpha')))
  .then(() => {
    return Promise.all(existRows.map((row) => {
      return knex(tableName)
      .update({ service: row.service === 'gamma' ? 'alpha' : row.service })
      .where('id', row.id)
    }))
  })
}
  • notNull列需要默认值吗?
  • 最好不要使用enum'因为它不是被动的...我将在代码中使用微小的整数字段和常量来控制可选字段

答案 1 :(得分:0)

从2018年9月5日起,这仍然是一个未解决的问题:https://github.com/tgriesser/knex/issues/1699(我相信您已将其打开!)。如果您使用的是PostgreSQL,那么这就是我要做的:

  1. 打开$ psql
  2. 连接到数据库> \c ...
  3. > \dt查看所有表格
  4. > \d user_associations查看该表的所有信息
  5. 查找支票的名称。应该是user_associations_service_check

然后重新进行迁移:

exports.up = knex =>
  knex.raw(`
    ALTER TABLE ONLY user_associations
    DROP CONSTRAINT user_associations_service_check;

    ALTER TABLE ONLY user_associations
    ADD CONSTRAINT user_associations_service_check
    CHECK ("service" = ANY (ARRAY['alpha'::text, 'beta'::text, 'gamma'::text]));
  `)

exports.down = knex =>
  knex.raw(`
    ALTER TABLE ONLY user_associations
    DROP CONSTRAINT user_associations_service_check;

    ALTER TABLE ONLY user_associations
    ADD CONSTRAINT user_associations_service_check
    CHECK ("service" = ANY (ARRAY['alpha'::text, 'beta'::text));
  `)

上面链接的有关您的knexjs问题的注释具有完成此任务的聪明实用程序功能:https://github.com/tgriesser/knex/issues/1699#issuecomment-402603481

答案 2 :(得分:0)

实际上,根据 Knex documentation 我们可以使用 alter() 语句:

const table = 'user_associations'

export async function up (knex) {
  return knex.schema.alterTable(table, (table) => {
    table.enu('service', ['alpha', 'beta', 'gamma']).notNullable().alter()
  })
}

export async function down (knex) {
  return knex.schema.alterTable(table, (table) => {
    table.enu('service', ['alpha', 'beta']).notNullable().alter()
  })
}