Shawn
Shawn

Reputation: 11391

How do I stop sequelize from creating an unwanted primary key when inserting data?

I have a sequelize model without any primary key:

module.exports = (sequelize, DataTypes) => {
  const usersDoors = sequelize.define('usersDoors',
    {
      user_uid: {
        type: DataTypes.UUID,
        allowNull: false,
      },
      door_uid: {
        type: DataTypes.UUID,
        allowNull: false,
      },
      property_manager_uid: {
        type: DataTypes.UUID,
        allowNull: true,
      },
      tenant_uid: {
        type: DataTypes.UUID,
        allowNull: true,
      },
      created_at: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
    },
    {
      tableName: 'users_doors',
      indexes: [
        {
          name: 'doors_users_indexes',
          unique: true,
          fields: ['user_uid', 'door_uid', 'property_manager_uid', 'tenant_uid'],
        },
      ],
      classMethods: {
        associate: (models) => {
          usersDoors.belongsTo(models.users, { foreignKey: 'user_uid' });
          usersDoors.belongsTo(models.doors, { foreignKey: 'door_uid' });
          usersDoors.belongsTo(models.propertyManagers, { foreignKey: 'property_manager_uid' });
          usersDoors.belongsTo(models.tenants, { foreignKey: 'tenant_uid' });
        },
      },
    });

  return usersDoors;
};

When I insert data (via sequelize), sequelize adds a composite primary key to the table which includes the first 2 columns (user_uid and door_uid). This is breaking my stuff and I don't want it.

How can I stop sequelize from creating an unwanted primary key when inserting data?

More details:

And finally, here is the sequelize migration for this model:

const tableName = 'users_doors';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable(tableName, {
      user_uid: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'users',
          key: 'uid',
        },
      },
      door_uid: {
        type: Sequelize.UUID,
        allowNull: false,
        references: {
          model: 'doors',
          key: 'uid',
        },
      },
      property_manager_uid: {
        type: Sequelize.UUID,
        allowNull: true,
        references: {
          model: 'property_managers',
          key: 'uid',
        },
      },
      tenant_uid: {
        type: Sequelize.UUID,
        allowNull: true,
        references: {
          model: 'tenants',
          key: 'uid',
        },
      },
      created_at: {
        type: Sequelize.INTEGER,
        allowNull: false,
      },
    })
      .then(() => {
        return queryInterface.addIndex('users_doors',
          ['user_uid', 'door_uid', 'property_manager_uid', 'tenant_uid'],
          {
            indexName: 'doors_users_indexes',
            indicesType: 'UNIQUE',
          });
      });
  },

  down: (queryInterface) => {
    return queryInterface.dropTable(tableName)
      .then(() => {
        return queryInterface.removeIndex('users_doors', ['user_uid', 'door_uid', 'property_manager_uid', 'tenant_uid']);
      });
  },
};

Upvotes: 3

Views: 6223

Answers (1)

piotrbienias
piotrbienias

Reputation: 7401

You just need to add attribute to sequelize model, as well as to the migrations, that would be your primary key

// in sequelize model definition
const usersDoors = sequelize.define('usersDoors',
{
  id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
  },
  user_uid: {
      type: DataTypes.UUID,
      allowNull: false,
  },
  // other fields

// in the migrations file
return queryInterface.createTable(tableName, {
  id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true
  },
  user_uid: {
      type: Sequelize.UUID,
      allowNull: false,
      references: {
          model: 'users',
          key: 'uid',
      },
  },
  // other fields

According to the documentation, when you create M:M relation, sequelize automatically creates a primary key which is composed of two foreign keys referencing to tables creating the relation (users and doors in your case)

The table will be uniquely identified by the combination of the keys of the two tables

EDIT

Assuming that you have used the belongsToMany on both users and doors model there is a way to avoid automatic creation of the unique index on user_uid and door_uid. You need to specify unique: false condition in the through object of the m:m relation initialisation (in both models to avoid any automatic unique constraints)

// in users model
users.belongsToMany(
    models.doors,
    {
        through: { model: models.usersDoors, unique: false },
        foreignKey: 'user_uid'
    }
);

// in doors model
doors.belongsToMany(
    models.users,
    {
        through: { model: models.usersDoors, unique: false },
        foreignKey: 'door_uid'
    }
);

Upvotes: 3

Related Questions