【问题标题】:Update enum column types in knex migration更新 knex 迁移中的枚举列类型
【发布时间】:2023-03-28 03:36:01
【问题描述】:

我正在寻找编写迁移字符串以将新字符串添加到枚举列类型。我正在尝试将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()
  })
}

【问题讨论】:

  • 尝试在一次迁移中首先删除列,然后在第二次迁移中创建它。如果一切都失败了,请尝试使用纯 sql 的 knex.raw

标签: javascript enums migration knex.js


【解决方案1】:
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 列需要默认值吗?
  • 最好不要使用枚举,因为它不是响应式的...我将在代码中使用微小的整数字段和常量来控制可选字段

【讨论】:

    【解决方案2】:

    截至 2018-09-05,这仍然是一个未解决的问题: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

    【讨论】:

      【解决方案3】:

      其实根据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()
        })
      }
      

      【讨论】:

        【解决方案4】:

        @Sombriks 提到的评论对我来说也很有效-

        1. 在一次迁移中首先删除“服务”列

          const table = 'user_associations'
          
          export.up= async function (knex) {
            await knex.schema.table(table, (table)=> {
              table.dropColumn('service');
            });
          }
          
          export.down= async function (knex) {
            await knex.schema.table(table, (table)=> {
              table.enu('service', ['alpha', 'beta').notNullable()
            });
          } ```
          
          
        2. 在另一个迁移的“服务”列中添加选项

          const table = 'user_associations'
          
          export.up= async function (knex) {
            await knex.schema.table(table, (table)=> {
              table.enu('service', ['alpha', 'beta', 'gamma']).notNullable()
            });
          }
          
          export.down= async function (knex) {
            await knex.schema.table(table, (table)=> {
              table.dropColumn('service');
            });
          } ```
          
          
          

        【讨论】:

        • 这会导致数据丢失。
        猜你喜欢
        • 2021-01-08
        • 2020-05-27
        • 2019-12-08
        • 2015-09-01
        • 2014-10-04
        • 2020-11-22
        • 1970-01-01
        • 2020-03-13
        • 2017-02-07
        相关资源
        最近更新 更多