【问题标题】:Sequelize composite unique constraintSequelize 复合唯一约束
【发布时间】:2016-04-12 09:59:18
【问题描述】:

定义模型:

export default function(sequelize, DataTypes) {
   return sequelize.define('Item', {
       minor: DataTypes.INTEGER,
       major: DataTypes.INTEGER,
   });
}

我可以将次要和主要对定义为复合 UNIQUE 约束吗?

【问题讨论】:

    标签: mysql node.js sequelize.js


    【解决方案1】:

    最近在V4中,Sequelize在查询接口上有一个方法addConstraint

    queryInterface.addConstraint('Items', {
      fields: ['minor', 'major'],
      type: 'unique',
      name: 'custom_unique_constraint_name'
    });
    

    【讨论】:

    • 现在已经过时了 -- 在 options 对象中将字段数组作为 fields 传递。
    • 如果有人对上面的评论感到困惑,由于@the-red-pea 的更新,它不再过时
    【解决方案2】:
    queryInterface.createTable('Item', {
        minor: {
            type: Sequelize.INTEGER,
        },
        major: {
            type: Sequelize.INTEGER,
        }
    }, {
        uniqueKeys: {
            Items_unique: {
                fields: ['minor', 'major']
            }
        }
    });
    

    【讨论】:

    • @MuhammadUmer 这是添加唯一复合键的最简单方法,奇怪的是它不受欢迎,甚至有人否决了这个答案
    • 奇怪的是,这在我的迁移文件中对我有用,但官方文档甚至说将其用作 major: { type: DataTypes.INTEGER, unique: 'compositeIndex'}, minor: { type: DataTypes.INTEGER, unique: 'compositeIndex'}
    • 这个答案对我有用,但我怎样才能提供一对以上的独特字段
    • { uniqueKeys: { Items_unique: { fields: ['minor', 'major'] }, Second_unique_pair: { fields: ['some_field_1', 'some_field_2'] } }@Hasan
    • 这个问题不是要求一个唯一的复合索引,而是一个通用的唯一复合约束。正确答案是stackoverflow.com/a/64712973/3158815
    【解决方案3】:

    这是一个简单的答案:

    major: { type: DataTypes.INTEGER, unique: 'compositeIndex'},
    minor: { type: DataTypes.INTEGER, unique: 'compositeIndex'}
    

    来源:http://docs.sequelizejs.com/en/latest/docs/models-definition/

    如果是连接表,您还可以通过 belongsToMany 关联创建唯一约束:

    Major = sequelize.define('major', {})
    Minor = sequelize.define('minor', {})
    
    Major.belongsToMany(Project)
    Minor.belongsToMany(User)
    

    来源:http://docs.sequelizejs.com/en/v3/docs/associations/

    就我而言,我想找到一种方法在我的迁移中强制执行此操作。我通过在我的 up 函数末尾附加一个原始 sql 查询来做到这一点:

      up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Item', {
      major: {
        allowNull: false,
        type: Sequelize.INTEGER
      },
      minor: {
        allowNull: false,
        type: Sequelize.INTEGER
      },
    })
    .then(function() {
      return queryInterface.sequelize.query(
        'ALTER TABLE `Item` ADD UNIQUE `unique_index`(`major`, `minor`)'
      );
    });
    

    相关问题:

    Sequelize, foreign keys as composite primary key

    Unique constraint across foreign keys in Sequelize model

    【讨论】:

    • 原来有多种选择。这个问题很难回答,因为它很大程度上取决于使用的 db 和 te sequalize 版本。这东西感觉不太稳定,最好避开它。
    • 实际上,它添加了 2 个复合唯一约束,一个在 property_manager_uid 和 tenand_uid 上,另一个在 user_uid 和 door_uid 上。有没有办法告诉 sequelize 不要添加任何主键或约束?为什么 sequelize 一开始就假定知道我想要什么?
    【解决方案4】:

    我使用addConstraint(...)解决了这个问题:

    await queryInterface.addConstraint('Item', {
      fields: ['minor', 'major'],
      type: 'unique',
      name: 'unique_constraint_name'
    });
    

    至少从 v6+ 开始。

    【讨论】:

      【解决方案5】:

      你可以这样使用:

      module.exports = {
        up: (queryInterface, Sequelize) => {
          return queryInterface.sequelize.transaction(t => {
            return queryInterface.createTable('item',
              {
                minor: {
                  type: Sequelize.INTEGER,
                },
                major: {
                  type: Sequelize.INTEGER,
                }
              }, { transaction: t }
            ).then(() => {
              return queryInterface.addConstraint(
                'item',
                ['minor', 'major'],
                {
                  type: 'unique',
                  name: 'Items_unique'
                },
                {
                  transaction: t
                }
              );
            });
          });
        },
        down: (queryInterface, Sequelize) => {
          return queryInterface.dropTable('item');
        }
      }
      

      【讨论】:

        【解决方案6】:

        对于 ES6 迁移

        const item = {
          up: (queryInterface, Sequelize) => queryInterface.createTable('Items', {
            minor: {
              type: Sequelize.INTEGER,
              allowNull: false,
            },
            major: {
              type: Sequelize.INTEGER,
              allowNull: false,
            },
          }).then(() => queryInterface.addConstraint('Items', ['minor', 'major'], {
            type: 'unique',
            name: 'composite_key_name'
          })),
          down: queryInterface => queryInterface.dropTable('Items')
        };
        
        export default item;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-15
          相关资源
          最近更新 更多