为什么我无法回滚我的迁移?

Why am I unable to rollback my migrations?

在我的技术主管在我们的应用程序中实施新的角色权限系统后,我一直无法通过回滚迁移来清除数据库。命令我通常运行是knex --env local migrate:rollback --all。似乎我的技术主管创建的新迁移文件(、12345_updatePermissions.js)是导致问题的原因,因为在我的终端中我返回了以下错误:

migration file "12345_updatePermissions.js" failed
migration failed with error: alter table "User" alter column "role" type text check ("role" in ('Admin', 'SuperUser', 'User')) using ("role"::text check ("role" in ('Admin', 'SuperUser', 'User'))) - syntax error at or near "check"
error: alter table "User" alter column role" type text check ("role" in ('Admin', 'SuperUser', 'User')) using ("role"::text check ("role" in ('Admin', 'SuperUser', 'User'))) - syntax error at or near "check"

我试着在 12345_updatePermissions.js 中寻找“支票”;但是,我找不到它。以下是12345_updatePermissions.js的内容:

const tableName = 'User';

exports.up = async (knex) => {
  await knex.schema.alterTable(tableName, (table) => {
    table.dropColumn('role');
  });
  await knex.schema.alterTable(tableName, (table) => {
    table.enu('role', ['Owner', 'Admin', 'Researcher', 'AdvancedResearcher', 'User']).defaultTo('User');
  });
};

exports.down = async (knex) => {
  await knex.schema.alterTable(tableName, (table) => {
    table.enu('role', ['Admin', 'SuperUser', 'User']).defaultTo('User').alter();
  });
};

我试过删除 exports.down 函数末尾的 alter() 方法,但无济于事(我真的不认为这会有帮助,但我很想尝试某物)。我不知道我还应该改变什么来解决这个问题。如果有人能帮助我理解错误,尤其是“检查”,并解释我如何修复它,我将不胜感激。

您可以检查枚举是如何创建的以及 alter 试图用它做什么:

https://runkit.com/embed/88ztxi2dme5a

const Knex = require('knex');

const knex = Knex({
  client: 'pg',
});

knex.schema.table('table', table => {
  table.enu('role', ['Admin', 'SuperUser', 'User']).defaultTo('User');
}).toSQL().map(row => console.log(row.sql))

// CREATES: "alter table \"table\" add column \"role\" text check (\"role\" in ('Admin', 'SuperUser', 'User')) default 'User'"

knex.schema.alterTable('table', table => {
  table.enu('role', ['Admin', 'SuperUser', 'User']).defaultTo('User').alter();
}).toSQL().map(row => console.log(row.sql))

// CREATES: alter table "table" alter column "role" type text check ("role" in ('Admin', 'SuperUser', 'User')) using ("role"::text::text check ("role" in ('Admin', 'SuperUser', 'User'))) 

因此,从中可以看出 .alter() 不支持更改 enu 类型的列,要更改它们,必须使用原始查询,这会删除旧的检查约束,然后创建一个新的具有更新值的一个。

经过一段时间的脚本尝试,我最终解决了我的问题。我所要做的就是在第 14 行将 table.enu('role', ['Admin', 'SuperUser', 'User']).defaultTo('User').alter() 换成 table.dropColumn('role')。以下是更新后的 12345_updatePermissions.js 的内容:

const tableName = 'User';

exports.up = async (knex) => {
  await knex.schema.alterTable(tableName, (table) => {
    table.dropColumn('role');
  });
  await knex.schema.alterTable(tableName, (table) => {
    table.enu('role', ['Owner', 'Admin', 'Researcher', 'AdvancedResearcher', 'User']).defaultTo('User');
  });
};

exports.down = async (knex) => {
  await knex.schema.alterTable(tableName, (table) => {
    table.dropColumn('role');
  });
};