sequelize: instance.destroy(...) does not return any information if rows has been deleted or not

using Sequelize 3.3.2

var user = User.build({ id: 1 }, { isNewRecord: false })
user.destroy()
.then(function(){
  console.log(arguments)
})

Code above always prints { '0': [] } no matter if row has been deleted or not. I am not sure if this is intentional, but it would useful to know that… Also returning option could be very useful (postgres) as I’ve mentioned in #4122

About this issue

  • Original URL
  • State: open
  • Created 9 years ago
  • Reactions: 1
  • Comments: 36 (22 by maintainers)

Most upvoted comments

@mickhansen @janmeier

instance.destroy() still returns empty array in postgresql. Any updates on this and why is it closed?

Any updates on this?

This doesn’t warrant opening a separate issue. But I have a question. The docs state destroy returns a Promise. That’s fine, but what does the Promise contain? I wish that was added into the docs. image

@kmlbdh Keep in mind that the maintainers of this library are working on it for what is basically free. If you really need this feature, you could open a PR and/or help review an existing one instead of making comments that are demotivating for the people that put in the work to improve this library.

In fact instance.save() also does not provide informations if record has been actually updated. Also I was wondering why Model.destroy (bulk destroy) returns (rows) from promise while Model.update returns ([rows]) (in array) from promise. To sum up:

var User = sequelize.define('User');
var user = User.build({ id: 1 }, { isNewRecord: false })

// bulk update
User.update({}, { where: { id: 1 } })
.then(function(){
  console.log(arguments) // { '0': [ 0 ] }
})

// bulk update with returning option
User.update({}, { where: { id: 1, returning: true } })
.then(function(){
  console.log(arguments) // { '0': [ 0, [] ] }
})

// bulk destroy
User.destroy({ where: { id: 1 } })
.then(function(){
  console.log(arguments) // { '0': 0 } - why not same as in bulkUpdate?
})

// update
user.save()
.then(function(){
  console.log(arguments) // { '0': USER_INSTANCE } - returned instance has only "id" and "updateAt" dataValues - there is no any information if any row has been updated
})

// update with returning option
user.save({ returning: true })
.then(function(){
  console.log(arguments) // { '0': USER_INSTANCE } - returned instance has "id", "updateAt" and other row values it has been actually updated
})

// destroy
user.destroy()
.then(function(){
  console.log(arguments) // { '0': [] } - no informations if rows has been deleted or not...
})

till 2022, there is no solution for this issue! I think working with this library is wasting time!

I am using v4.37.5 and Model.destroy() still returns an empty array. However the document says:

Return:

Promise<Integer> The number of destroyed rows

Not sure if I missed anything?

I’ve started working on this in PR #4299. No tests yet. So far I’ve managed to make it work like this:

instance.update({}, options)
// beforeUpdate: (instance, options)
// afterUpdate: (instance, options) - instance is null if not updated, instance contains fetched data if options.returning
.then(function(instance){}) // - instance is null if not updated, instance contains fetched data if options.returning

instance.destroy(options)
// beforeDestroy: (instance, options)
// afterDestroy: (instance, options) - instance is null if not deleted, instance contains fetched (deleted) data if options.returning
.then(function(instance){}) // - instance is null if not deleted, instance contains fetched (deleted) data if options.returning

Model.update({}, options)
// beforeBulkUpdate (options)
// afterBulkUpdate (options)
.then(function([rows, instances]){}) // instances not present if result array if !options.returning

Model.destroy({}, options)
// beforeBulkDestroy (options)
// afterBulkDestroy (options)
.then(function([rows, instances]){}) // instances not present if result array if !options.returning

One thing I can’t figure out is how to deal with bulkUpdate and bulkDestroy and hooks. It is possible to pass individualHooks option to both methods and both beforeUpdate/Destroy and afterUpdate/Destroy hooks will be executed for each instance. However, since there is returning option, it would be useful to able to perform bulkUpdate/bulkDestroy WITHOUT individual before hooks, but WITHIN individual after hooks. What do you think guys?

Also I was wondering if it wouldn’t be useful to pass results of bulkUpdate and bulkCreate ([rows, instances]) to afterBulkUpdate and afterBulkDelete hooks:

afterBulkUpdate: function([rows, instances], options){ ... }

I noticed this problem when investigating another issue, I was already aware of this but didn’t know there was an issue for it!

Hmm, the problem is even deeper I guess. When you call ANY instance method that affects databse (instance.save, instance.update, instance.destroy) you NEVER know if that rows still exists in db or not… Instance is just server side description of row that is not actually synced with database - so in @mickhansen example above theoretically even if update failed, it does not mean that row does not exists when it comes to instance.addAssociation().