Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize composite unique constraint

Defining model:

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

Can I define the pair minor and major as a composite UNIQUE constraint?

like image 974
speedingdeer Avatar asked Jan 07 '16 20:01

speedingdeer


People also ask

How do you define a composite key in Sequelize?

You can create composite primary keys in Sequelize by specifying primaryKey: true against more than one column. E.g. how can we associate a table to this composite key.

How do I make an email unique in Sequelize?

One way to solve this is by using sequelize. sync() to create your table according to the schema specified in the model if the table exists then you should pass {force: true} to the sync method, the table will be dropped and a new one will be created.


4 Answers

Recently, in V4, Sequelize has a method addConstraint on the query interface:

queryInterface.addConstraint('Items', {   fields: ['minor', 'major'],   type: 'unique',   name: 'custom_unique_constraint_name' }); 
like image 110
alockwood05 Avatar answered Oct 05 '22 14:10

alockwood05


queryInterface.createTable('Item', {     minor: {         type: Sequelize.INTEGER,     },     major: {         type: Sequelize.INTEGER,     } }, {     uniqueKeys: {         Items_unique: {             fields: ['minor', 'major']         }     } }); 
like image 34
vikasThakur.com Avatar answered Oct 05 '22 12:10

vikasThakur.com


Here is the simple answer:

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

source: https://sequelize.org/master/manual/model-basics.html#column-options

// Creating two objects with the same value will throw an error. > The unique property can be either a
// boolean, or a string. If you provide the same string for > multiple columns, they will form a
// composite unique key.
uniqueOne: { type: DataTypes.STRING,  unique: 'compositeIndex' },
uniqueTwo: { type: DataTypes.INTEGER, unique: 'compositeIndex' },

You can also create a unique constraint through belongsToMany associations if it's a join table:

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

Major.belongsToMany(Project)
Minor.belongsToMany(User)

Source: http://docs.sequelizejs.com/en/v3/docs/associations/

In my case, I wanted to find a way to enforce this with my migration. I did this by appending a raw sql query at the end of my up function:

  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`)'
  );
});

Related Questions:

Sequelize, foreign keys as composite primary key

Unique constraint across foreign keys in Sequelize model

like image 43
Jake Avatar answered Oct 05 '22 12:10

Jake


I solved this by using addConstraint(...):

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

This is as of at least v6+.

like image 43
Chidiebere Avatar answered Oct 05 '22 13:10

Chidiebere