【问题标题】:How to define unique index on multiple columns in sequelize如何在sequelize中定义多列的唯一索引
【发布时间】:2017-06-30 22:11:23
【问题描述】:

如何在 sequelize.例如,我想在 user_id、count 和 name 上添加唯一索引。

var Tag = sequelize.define('Tag', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        },
        user_id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        count: {
            type: DataTypes.INTEGER(11),
            allowNull: true
        },
        name: {
            type: DataTypes.STRING,
            allowNull: true,
        })

【问题讨论】:

    标签: mysql sequelize.js


    【解决方案1】:

    你可以参考这个文档http://docs.sequelizejs.com/en/latest/docs/models-definition/#indexes

    您将需要如下所示更改您的定义并调用同步

    var Tag = sequelize.define('Tag', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        },
        user_id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
        },
        count: {
            type: DataTypes.INTEGER(11),
            allowNull: true
        },
        name: {
            type: DataTypes.STRING,
            allowNull: true,
        }
    },
    {
        indexes: [
            {
                unique: true,
                fields: ['user_id', 'count', 'name']
            }
        ]
    });
    

    【讨论】:

    • 这对我不起作用。以下任何答案都没有。我正在尝试运行与此等效的查询:CREATE TABLE scores (id INT PRIMARY KEY NOT NULL, oppId INT NOT NULL, oppType TEXT NOT NULL, tree TEXT NOT NULL, version INT NOT NULL, score JSON NOT NULL, CONSTRAINT uniq_scores UNIQUE(oppId, oppType, tree, version));。当我将唯一索引与 sequelize 一起使用时,我仍然能够在这些列中创建具有相同值的两行。其他人有这些问题吗?
    • @clu 它,因为只有在续集自己处理
    【解决方案2】:

    我有同样的问题将复合唯一约束应用于多个 列,但不适用于 Mysql、Sequelize(4.10.2) 和 NodeJs 8.9.4 终于通过下面的代码修复了。

    queryInterface.createTable('actions', {
      id: {
          type: Sequelize.INTEGER,
          primaryKey: true,
          autoIncrement: true
      },
      system_id: {
          type: Sequelize.STRING,
          unique: 'actions_unique',
      },
      rule_id: {
          type: Sequelize.STRING,
          unique: 'actions_unique',
      },
      plan_id: {
          type: Sequelize.INTEGER,
          unique: 'actions_unique',
      }
    }, {
      uniqueKeys: {
          actions_unique: {
              fields: ['system_id', 'rule_id', 'plan_id']
          }
      }
    });
    

    【讨论】:

    • 这应该是公认的答案。调用 sync 不利于保持迁移轨迹。
    • 另外,对我来说,我只是提到了unique: 'actions_unique' 我想在复合唯一规则中使用的列。没有添加uniqueKeys 选项。
    • 可以确认,在 MySQL 5.7 和 Sequelize 5.21.2 中,仅在相应字段上提及唯一标签没有任何作用;只有uniqueKeys 似乎有效。通过运行迁移和不运行迁移进行检查,然后使用“显示创建表”检查 mySQL。
    【解决方案3】:

    如果接受的那个不起作用,请尝试以下代码。就我而言,它对我有用,而不是被接受的。

    var Tag = sequelize.define('Tag', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        },
        user_id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            unique: 'uniqueTag',
        },
        count: {
            type: DataTypes.INTEGER(11),
            allowNull: true,
            unique: 'uniqueTag',
        },
        name: {
            type: DataTypes.STRING,
            allowNull: true,
            unique: 'uniqueTag',
        }
    });
    

    【讨论】:

    • 现在不能使用。无法与alter: true 选项同步...
    • 嗨@RahmatAli 不明白我在哪里使用alter: true
    • 您可以在sequelize的sync函数中使用alter: true。因此,当sequelize 将models 与数据库同步时,sequelize 使用模型中更改的列更改数据库列。建议通过indexes 使用unique 属性。否则,如果在sync 函数中与alter: true 一起使用,会出现一些错误。更多alter属性请参考文档:link
    【解决方案4】:

    我尝试在单个列上创建索引。 这对我有用。希望这会有所帮助。

    型号

    module.exports = (sequelize, DataTypes) => {
      const Tag = sequelize.define(
        "Tag",
        {
          name: { type: DataTypes.STRING, unique: true },
          nVideos: DataTypes.INTEGER
        },
        {
          indexes: [
            {
              unique: true,
              fields: ["name"]
            }
          ]
        }
      );
    
      return Tag;
    };
    

    迁移

    module.exports = {
      up: (queryInterface, Sequelize) => {
        return queryInterface.createTable(
          "Tags",
          {
            id: {
              allowNull: false,
              autoIncrement: true,
              primaryKey: true,
              type: Sequelize.INTEGER
            },
            name: {
              type: Sequelize.STRING,
              unique: "unique_tag"
            },
            nVideos: { type: Sequelize.INTEGER },
            createdAt: {
              allowNull: false,
              type: Sequelize.DATE
            },
            updatedAt: {
              allowNull: false,
              type: Sequelize.DATE
            }
          },
          {
            uniqueKeys: {
              unique_tag: {
                customIndex: true,
                fields: ["name"]
              }
            }
          }
        );
      },
      down: queryInterface => {
        return queryInterface.dropTable("Tags");
      }
    };
    
    

    【讨论】:

    • @Sandeep 你是救世主。尝试了很多选择,只有这对我有用。非常感谢。
    • 无法使其与这些版本一起使用.. "sequelize": "^6.3.5", "sequelize-hierarchy": "git+github.com/jsanta/sequelize-hierarchy.git"
    【解决方案5】:

    我更喜欢使用复合唯一的 sequelize 同步方法,如果不传递索引名称,在索引数组中添加多个索引时会出现如下错误。

    错误:SequelizeDatabaseError:标识符名称“LONG_NAME”太长

    module.exports = function (sequelize: any, DataTypes: any) {
    return sequelize.define('muln_user_goals_transaction', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
        },
        name: {
            type: DataTypes.STRING(),
            allowNull: false,
        },
        email: {
            type: DataTypes.STRING(),
            allowNull: false,
        },
        phone: {
            type: DataTypes.STRING(),
            allowNull: false,
        },
        amount: {
            type: DataTypes.INTEGER(8),
            allowNull: false
        },
        deleted: {
            type: DataTypes.BOOLEAN,
            defaultValue: false,
        },
    }, {
        tableName: 'muln_user_goals_transaction',
        timestamps: false,
        indexes: [
            {
                name: 'unique_index',
                unique: true,
                fields: ['name', 'email', 'phone', 'amount', 'deleted']
            }
        ],
        defaultScope: {
            where: {
                deleted: false
            }
        }
    });
    };
    

    【讨论】:

    • 我只需要知道您可以将'deleted' 添加到索引中,以防您正在处理软删除。谢谢
    【解决方案6】:

    Sequelize 复合唯一(手动)

    module.exports = {
      up: (queryInterface, Sequelize) => {
        return queryInterface.createTable('Model', {
          id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER
          },
          fieldOne: {
            type: Sequelize.INTEGER,
            unique: 'uniqueTag',
            allowNull: false,
            references: {
              model: 'Model1',
              key: 'id'
            },
            onUpdate: 'cascade',
            onDelete: 'cascade'
          },
          fieldsTwo: {
            type: Sequelize.INTEGER,
            unique: 'uniqueTag',
            allowNull: false,
            references: {
              model: 'Model2',
              key: 'id'
            },
            onUpdate: 'cascade',
            onDelete: 'cascade'
          },
          createdAt: {
            allowNull: false,
            type: Sequelize.DATE
          },
          updatedAt: {
            allowNull: false,
            type: Sequelize.DATE
          }
        })
        .then(function() {
          return queryInterface.sequelize.query(
            'ALTER TABLE `UserFriends` ADD UNIQUE `unique_index`(`fieldOne`, `fieldTwo`)'
          );
        });
      },
      down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable('Model');
      }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 2014-06-12
      • 2016-05-28
      相关资源
      最近更新 更多