Knex: 问题:更新 knex 迁移中的枚举列类型

创建于 2016-09-27  ·  10评论  ·  资料来源: knex/knex

堆栈溢出

我正在寻找编写迁移字符串以将新字符串添加到 enum 列类型。 我正在尝试将gammaservice列中。

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

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()
  })
}
PR please

最有用的评论

仅适用于任何想知道 Postgres 9 中的代码 _might_ 外观的人

const formatAlterTableEnumSql = (
  tableName,
  columnName,
  enums,
) => {
  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      "'::text, '"
    )}'::text]));`,
  ].join('\n');
};


exports.up = async function up(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
      'enum3',
    ])
  );
};

exports.down = async function down(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
    ])
  );
};

所有10条评论

碰上这个,有什么方法可以使用alter API?

枚举当前使用检查约束完成,并且.alter()对它们没有任何特殊处理......

一个问题是.alter()不知道列的原始类型是什么,这就是为什么它不知道是否应该删除枚举的旧检查约束。

据我所知,目前只能通过删除旧的并创建新的检查约束来使用knex.raw更改允许的枚举值...

我认为它可以通过一些drop old constraint if exist ,然后如果列的更改类型是枚举,则创建一个新的。

我很想看到这个功能被实现。

@elhigu我写了一个自定义枚举查询,以便我可以使用 Postgres 枚举,但是 Postgres 社区中存在一些关于检查条件与枚举的争论

仅适用于任何想知道 Postgres 9 中的代码 _might_ 外观的人

const formatAlterTableEnumSql = (
  tableName,
  columnName,
  enums,
) => {
  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      "'::text, '"
    )}'::text]));`,
  ].join('\n');
};


exports.up = async function up(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
      'enum3',
    ])
  );
};

exports.down = async function down(knex) {
  await knex.raw(
    formatAlterTableEnumSql('myTableName', 'myColumnName', [
      'enum1',
      'enum2',
    ])
  );
};

@holloway感谢您提供迁移代码示例。 正是我正在寻找的。 不过我遇到了一个问题。 'myColumnName' 在迁移时抛出错误。 该消息说“列'mycolumnname' 不存在”。 请注意,camelCase 现在丢失了。 关于如何解决这个问题的任何想法?

@Jordan24你能分享你的代码吗?

'use strict';

const formatAlterTableEnumSql = (tableName, columnName, enums) => {

  const constraintName = `${tableName}_${columnName}_check`;
  return [
    `ALTER TABLE ${tableName} DROP CONSTRAINT IF EXISTS ${constraintName};`,
    `ALTER TABLE ${tableName} ADD CONSTRAINT ${constraintName} CHECK (${columnName} = ANY (ARRAY['${enums.join(
      `'::text, '`
    )}'::text]));`
  ].join('\n');
};


exports.up = async function up(knex) {

  await knex.raw(
    formatAlterTableEnumSql('item_messages', 'sentMethod', [
      'Web App', 'Email', 'Text Message', 'Log Conversation'
    ])
  );
};

exports.down = async function down(knex) {

  await knex.raw(
    formatAlterTableEnumSql('item_messages', 'sentMethod', [
      'Web App', 'Email', 'Text Message'
    ])
  );
};

如果我将 columnName 用双引号括起来,则会出现语法错误,因为原始代码中未删除单引号。
我想我可能会放弃这个函数,只写两次原始代码。

@Jordan24如果没有引号,PostgreSQL

硬编码除“枚举”之外的所有内容以解决它。 感谢@kibertoad 的提示!

此页面是否有帮助?
0 / 5 - 0 等级