Skip to content

Model.update() issues SQL statement with updated_at as only field (sequelize v4.0.0-2) #7101

@iamjochem

Description

@iamjochem

hi there,

I think the following is a bug , most people will not notice it happening (it's non-destructive) but in my case I am triggering side-effects in "after update" hooks (with individualHooks turned on - although my tests show that the individualHooks option has no bearing on this problem) which I really only want if some record(s) is/are actually mutated.

I am using the Sequelize v4 beta but from looking at the relevant source I think the described behaviour has been around for a while!

What you are doing?

Performing a Model.update(fields, options) call with a fields object that contains no keys that are valid fields/attributes.

The following function can be run to reproduce the problem, please call it with an instance of Sequelize:

function runtest(db)
{
    /* SETUP ... */
    var TEU  = db.define('TestEmptyUpdate', {
        name : db.Sequelize.DataTypes.STRING,
        type : db.Sequelize.DataTypes.STRING
    });

    var data = { name : 'untested' + (+new Date), type : 'foo' }
    var junk = { not_a_field : true, also_not_a_field : 'really' };

    return TEU
        .sync()
        .then(function() { return TEU.create(data, { logging : logsql }); })

        /**
         * TEST: updating via model.update() with INVALID fields (does not trigger a query - I feel this is INCORRECT)
         */
        .then(function(inst) { return TEU.update(junk, { where : { id : inst.id }, logging : logsql }); })

        /**
         * CONTROL: updating instance with INVALID fields (does not trigger a query - I feel this is correct)
         */
        .then (function() { return TEU.findOne(); })
        .then (function(inst) { return inst.update(junk, { logging : logsql }); })

        /**
         * CONTROL: updating instance with VALID fields (does trigger a query - this is definitely correct :-)
         */
        .then (function() { return TEU.findOne(); })
        .then (function(inst) { return inst.update( { name : 'tested' }, { logging : logsql }); })


        .catch(console.error)
        .then (function() { return TEU.drop(); })
        .then (function() { process.exit(); })
        .catch(function(e) { console.error(e); process.exit(1); })
        ;
}

What do you expect to happen?

I expect the query not to occur when no valid fields have been specified for update (updated_at, created_at, etc should only be added to the list of fields to update if that list is not empty (empty after having been filtered for invalid fields/attributes), Model.update() should resolve and give ZERO for the "affected rows" value.

What is actually happening?

Sequelize is running a query like the following (when running TEU.update(junk, ...) in the code above):

UPDATE `TestEmptyUpdates` SET `updatedAt`='2017-01-11 13:40:57' WHERE `id` = 1

Dialect: mysql
Database version: Ver 14.14 Distrib 5.7.16, for osx10.10
Sequelize version: v4.0.0-2

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugDEPRECATED: replace with the "bug" issue type

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions