删除 sequelize 迁移中的约束

Posted

技术标签:

【中文标题】删除 sequelize 迁移中的约束【英文标题】:Remove constraints in sequelize migration 【发布时间】:2015-04-08 15:21:38 【问题描述】:

我正在通过migrations.changeColumn 函数在迁移中添加unique 约束。

添加约束是可行的,但是由于您需要提供“向后迁移”,因此以同样的方式删除它是行不通的。向后迁移时不会出现任何错误,但再次应用前向迁移会导致Possibly unhandled SequelizeDatabaseError: relation "myAttribute_unique_idx" already exists

(使用的数据库是postgres)

module.exports = 
  up: function (migration, DataTypes, done) 
    migration.changeColumn(
      'Users',
      'myAttribute',
      
        type: DataTypes.STRING,
        unique: true                 // ADDING constraint works
      
    ).done(done);
  ,

  down: function (migration, DataTypes, done) 
    migration.changeColumn(
      'Users',
      'myAttribute',
      
        type: DataTypes.STRING,
        unique: false                // REMOVING does not
      
    ).done(done);
  
;

我也尝试过使用removeIndex

migration.removeIndex('Users', 'myAttribute_unique_idx').done(done);

但在还原迁移时会出现以下错误:

Possibly unhandled SequelizeDatabaseError: cannot drop index "myAttribute_unique_idx" because constraint myAttribute_unique_idx on table "Users" requires it

【问题讨论】:

你能在不使用 sequelize.query 的情况下做到这一点吗? 【参考方案1】:

从 2017 年开始,使用 Sequelize 4.4.2,我们可以使用 queryInterface API 移除约束:

queryInterface.removeConstraint(tableName, constraintName)

文档是here。

【讨论】:

更新了文档here 对我不起作用,抛出错误:找不到具有特定名称的约束。即使约束确实存在并且在原始查询下面很好地删除了它【参考方案2】:

不幸的是,sequelize 没有内置的迁移方法来移除约束。这就是为什么在删除密钥之前您需要进行原始查询。

down: function (migration, DataTypes) 
  migration.sequelize.query(
    'ALTER TABLE Users DROP CONSTRAINT myAttribute_unique_idx;'
  );
  migration.removeIndex('Users', 'myAttribute_unique_idx');

  return;

【讨论】:

非常感谢。文档对此限制不是很清楚。 是的,文档暗示您可以使用references: null,但这不起作用。这更加糟糕,因为我找不到命名约束的方法,这意味着我的迁移与特定版本的 sequelize 紧密耦合。糟糕! 如果名称不是小写,请确保将原始查询中的表名放在双引号中:'ALTER TABLE "Users" DROP CONSTRAINT myAttribute_unique_idx;'【参考方案3】:

如果你想删除约束,Sequelize 有removeConstraint() 方法。 所以你可以使用这样的东西:

return queryInterface.removeConstraint('users', 'users_userId_key', )

其中users 是我的表名,users_userId_key 是索引或约束名称,如果您有要删除的唯一约束(比如说),通常采用attributename_unique_key 的形式。

【讨论】:

【参考方案4】:

如果你想删除你应该使用的索引:

down: function (migration, DataTypes) 
    return migration.removeIndex('Users', 'myAttribute_unique_idx');

return 用于使用 promise 样式而不是回调。这是sequelize推荐的。

您也可以按照此处所述自行处理索引的创建: http://sequelize.readthedocs.org/en/latest/docs/migrations/#addindextablename-attributes-options

【讨论】:

【参考方案5】:

只需这样做:

 await queryInterface.removeConstraint("Users","myAttribute" )

【讨论】:

以上是关于删除 sequelize 迁移中的约束的主要内容,如果未能解决你的问题,请参考以下文章

正确删除并使用 sequelize 创建 ENUM?

Sequelize 迁移中的关联

使用随时间变化的模型为 Sequelize 制作可重现的迁移字符串?

使用Sequelize添加/删除字段

使用sequelize时如何自动创建迁移文件?

使用迁移中的 Sequelize bulkUpdate,我可以访问 `this` 来生成价值吗?