Skip to content

Where not being correctly generated (upsert) #3065

@glacorSoul

Description

@glacorSoul

I came with up with a scenario where the where clause is not being correctly generated for a N:M association Model with postgres dialect.

Model definitions:

var User = con.define('User', {
    username: Sequelize.TEXT,
    password: Sequelize.TEXT,
    salt: Sequelize.STRING.BINARY,
    roles: Sequelize.ARRAY(Sequelize.TEXT),
    email: {
        type: Sequelize.TEXT,
        unique:{name: 'email', msg: 'Email is already registred'},
        validate: {
            notEmpty: true,
            isEmail: true,
        }
    }
},{
    timestamps: false
});

var Complaint = con.define('Complaint', {
    message: Sequelize.TEXT,
    archieved: Sequelize.BOOLEAN,
    category: Sequelize.TEXT,
    location: Sequelize.TEXT,
    createdAt: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.NOW,
        get: function(){
            return moment(this).format("ddd, MMM DD YYYY, hh:mm:ss")
        },
    },
    updatedAt: Sequelize.DATE,
},{
    timestamps: false,
    instanceMethods: {
        votesUp: function() { /*code ommited*/  },
        votesDown: function() { /*code ommited*/ }
    }
});

var UserComplaint = con.define('UserComplaint', {
    liked: Sequelize.BOOLEAN,  
    unliked: Sequelize.BOOLEAN,  
    following: Sequelize.BOOLEAN,  
    lastView: Sequelize.DATE
},{
    timestamps: false
});

User.hasMany(Complaint);
Complaint.belongsTo(User);

Complaint.belongsToMany(User, {
    through: UserComplaint,
    as: 'follower'
});
User.belongsToMany(Complaint, {
    through: UserComplaint,
    as: 'following'
});

I'm calling upsert as follows:

data.userComplaint.upsert(
    {UserId:req.session.userid, ComplaintId:req.body.complaintid, unliked: req.body.vote}, 
    {UserId:req.session.userid, ComplaintId:req.body.complaintid}
).then(function(){
    res.send('ok');
});

The following query is being generated, and it's missing one of the primmary key attributes of the relation, the ComplaintId

CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert() RETURNS integer AS $$ BEGIN 
INSERT INTO "UserComplaints" ("liked","UserId","ComplaintId") 
VALUES (false,2,'7'); RETURN 1; 
EXCEPTION WHEN unique_violation THEN 
UPDATE "UserComplaints" SET "liked"=false,"UserId"=2,"ComplaintId"='7' 
WHERE ("UserId"=2) /*Missing and with ComplaintId*/; RETURN 2; END; $$ LANGUAGE plpgsql; 

SELECT * FROM pg_temp.sequelize_upsert();

I also did a small debugging on my model and found that you have several property that relates to the primary key:

data.userComplaint.primaryKeyField - "UserId"
data.userComplaint.primaryKeyAttribute - "UserId"
data.userComplaint.primaryKeyAttributes - ["UserId", "ComplaintID"]
data.userComplaint.primaryKeys - {Complaitd: {/*...*/}, UserId:  {/*...*/}}

It seems however that in your upsert method you are using the primaryKeyField to generate the where.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions