Knex: 如何更改迁移内列中的可为空约束?

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

我正在尝试更改列上的约束,但这似乎只是尝试重新创建列并失败。

exports.up = function(knex, Promise) {  
  return knex.schema.table("images", function(table) {
    table.string("checksum").notNullable();
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.table("images", function(table) {
    table.string("checksum").nullable();
  });
};
PR please feature request schema

最有用的评论

对于那些从谷歌来到这里的人,语法是:

将现有的 nonNullable 列转换为可为空的(如果您希望 nonNullable 为可为空,则反转向上/向下)。

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

所有10条评论

@Rush我真的不认为.nullable().notNullable()用于此目的。 在我看来你想要运行类似的东西

ALTER TABLE tableName ALTER COLUMN columnName DROP NOT NULL
ALTER TABLE tableName ALTER COLUMN columnName SET NOT NULL

目前,除了.raw之外,我在 API 中找不到任何可以处理此问题的内容。

@rhys-vdw 您对此有何看法? .dropNotNull() / .setNotNull()或类似的可以成为 schemaBuilder 的一个有价值的补充吗? 它与.dropForeign()的实现非常相似。

.dropNotNull()/.setNotNull() 或类似的东西可以成为 schemaBuilder 的一个有价值的补充吗?

是的,但可能是.dropNullable(...columnNames).setNullable(...columnNames)

@rhys-vdw 再想一想,我觉得这对 postgres 以外的任何方言来说都太不方便了。 我个人认为以下问题没有好的解决方案:

Postgres dropNullable: ALTER TABLE table ALTER COLUMN columnName DROP NOT NULL
Postgres setNullable: ALTER TABLE table ALTER COLUMN columnName SET NOT NULL

MSSQL dropNullable: ALTER TABLE table ALTER COLUMN columnName columnType NULL
MSSQL setNullable: ALTER TABLE table ALTER COLUMN columnName columnType NOT NULL

MySQL/Maria/Oracle dropNullable: ALTER TABLE table MODIFY columnName columnType NULL;
MySQL/Maria/Oracle setNullable: ALTER TABLE table MODIFY columnName columnType NOT NULL;

Sqlite: No support?

根据您运行的方言,它会导致不一致的参数。 Postgres 只想要名称,而其他人想要名称 + 数据类型(+ 默认值?)。

你怎么看,值得吗?

我们曾经同时支持 SQLite 和 Postgres,但 SQLite 是如此不同,以至于再多的抽象都无法隐藏它……所以在这种情况下抛出异常可能是正确的。 Rails 的 ActiveRecord 迁移确实支持更改约束,所以也许这就是获得灵感的地方?

毕竟这是可以实施的。 我已经做了一个 PR。

+1 - 我也刚遇到这个问题,它有点阻碍。 任何时候您需要进行迁移以映射不可为空列的表示时,您都需要这样做。

@morungos并不是真正的阻滞剂,因为您始终可以访问 knex.raw 以获取 knex 没有专门 API 的内容(编写迁移时有很多内容)。

如果此拉取请求完成,此问题也可以关闭https://github.com/tgriesser/knex/pull/1759

是的,我用过 .raw 几次,但如果它变成完整的语句,它就会开始质疑膝盖迁移的整个使用。 最后,我确实使用了一种解决方法:只是默认为一些非空的奇怪值,然后应用映射规则来更新值,然后删除原始值。 但是,如果您要强制执行完整性,则很难做到这一点,尤其是在 MySQL 中,即使在中间步骤中也要求完整性是一种令人讨厌的习惯。

对于那些从谷歌来到这里的人,语法是:

将现有的 nonNullable 列转换为可为空的(如果您希望 nonNullable 为可为空,则反转向上/向下)。

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

仅供参考,如果您尝试将nullable更改nonNullable您首先需要在该列中填充一些内容,否则会出现错误。

对于那些从谷歌来到这里的人,语法是:

将现有的 nonNullable 列转换为可为空的(如果您希望 nonNullable 为可为空,则反转向上/向下)。

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

arconus picture arconus  ·  3评论

lanceschi picture lanceschi  ·  3评论

mattgrande picture mattgrande  ·  3评论

saurabhghewari picture saurabhghewari  ·  3评论

npow picture npow  ·  3评论