Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sequelize destroy record with join

In my model there is a Users table, and a UserPhones table. User.id is a foreign key in UserPhones.

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
      userid       : {
        type        : DataTypes.UUID,
        primaryKey  : true,
      },
      username : DataTypes.STRING,
    },
    {
      classMethods: {
        associate: (models) => {       
          models.User.hasOne(models.UserPhone, {foreignKey: 'userId'});
        }
      }
    });

  return User;
};


module.exports = (sequelize, DataTypes) => {
  const UserPhone = sequelize.define('UserPhone', {
      id              : {
        type        : DataTypes.UUID,
        primaryKey  : true,
      },
      userId   : {
        type      : DataTypes.UUID,
        references: {
          model     : require('.').User,
          key       : 'userid',
          deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE
        }
      },
      phoneNumber     : {
        type: DataTypes.STRING
      }
    },
    {
      classMethods: {
        associate: (models) => {
          models.UserPhone.belongsTo(models.User, {foreignKey: 'userId'});
        }
      }
    }
  );
  return UserPhone;
};

Destroying a phoneNumber is easy:

UserPhone.destroy({where: {phoneNumber: '123456789'}};

I would like to delete all users that have a specific phone number with sequelize. Even better, delete all users that have one of an array of phone numbers.

like image 595
eran Avatar asked Nov 30 '16 13:11

eran


People also ask

How does Sequelize work?

Under the hood, Sequelize will generate and execute a JOIN query, as you’ll see later. There are four types of association methods that you can use in Sequelize: These four methods can be used to create One-To-One, One-To-Many, and Many-To-Many relationships between your models. In the example we have, one Users row can have many Invoices rows.

How to use join or eager query in node Sequelize?

When you want use join or eager query in node sequelize then first you have to declare relation or association between tables. Sequelize provides four types of associations that should be combined to create them: relation or association in node sequelize example. 1const A = sequelize.define('A', /* ... */); 2const B = sequelize.define('B', /* ...

What is the Sequelize include option in a model finder?

The Sequelize include option is commonly added in a model finder method ( findOne (), findAll (), etc.) This option is used to add a JOIN clause to the generated SQL query, enabling you to retrieve data from multiple tables with one query. For example, suppose you have two related SQL tables named Cities and Countries.

What are the different fields in a Sequelize column?

Each field can either be a string containing the name of the field, a sequelize object (e.g sequelize.fn ), or an object with the following attributes: attribute (field name), length (create a prefix index of length chars), order (the direction the column should be sorted in), collate (the collation (sort order) for the column)


2 Answers

I do not think it is possible to do a DELETE and a JOIN query at the same time.

Therefore,

I would like to delete all users that have a specific phone number with sequelize.

UserPhone.findAll({attributes: ['userId'], where: {phoneNumber: '1234'}}
.then(function (userIds) {
    if (userIds.length === 0) 
       return Promise.resolve(true) //nothing to delete
    return User.destroy({where: {id: {$in: userIds}}});
})

Delete all users that have one of an array of phone numbers.

var array = ['123', '456'];
UserPhone.findAll({attributes: ['userId'], where: {phone: { $in: array }}}
.then(function (userIds) {
    if (userIds.length === 0) 
       return Promise.resolve(true) //nothing to delete
    return User.destroy({where: {id: {$in: userIds}}});
})
like image 82
Maria Ines Parnisari Avatar answered Oct 10 '22 17:10

Maria Ines Parnisari


Sequelize does not currently support an include option on the destroy method: https://sequelize.org/master/class/lib/model.js~Model.html#static-method-destroy

If you want to avoid multiple sql statements, you will have to write a raw query: https://sequelize.org/master/manual/raw-queries.html

Eg. for a SQL Server solution, the following would work:

await sequelize.query(`
    DELETE User
    FROM User
    INNER JOIN UserPhone ON UserPhone.userId = User.userId
    WHERE UserPhone.phoneNumber = :phoneNumber
`, { replacements: { phoneNumber: '1234'} })
like image 38
Pelle Jacobs Avatar answered Oct 10 '22 16:10

Pelle Jacobs