Skip to content

Commit

Permalink
fix(model): updateOnDuplicate handles composite keys (sequelize#11984)
Browse files Browse the repository at this point in the history
  • Loading branch information
thaddeusmt authored and mynameisrufus committed Aug 19, 2020
1 parent 3d2df28 commit 5e92d8b
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2707,7 +2707,7 @@ class Model {
// Get primary keys for postgres to enable updateOnDuplicate
options.upsertKeys = _.chain(model.primaryKeys).values().map('field').value();
if (Object.keys(model.uniqueKeys).length > 0) {
options.upsertKeys = _.chain(model.uniqueKeys).values().filter(c => c.fields.length === 1).map(c => c.fields[0]).value();
options.upsertKeys = _.chain(model.uniqueKeys).values().filter(c => c.fields.length >= 1).map(c => c.fields).reduce(c => c[0]).value();
}
}

Expand Down
111 changes: 111 additions & 0 deletions test/integration/model/bulk-create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,117 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(people[1].name).to.equal('Bob');
});
});

it('when the composite primary key column names and model field names are different', function() {
const Person = this.sequelize.define('Person', {
systemId: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
field: 'system_id'
},
system: {
type: DataTypes.STRING,
allowNull: false,
primaryKey: true,
field: 'system'
},
name: {
type: DataTypes.STRING,
allowNull: false,
field: 'name'
}
}, {});

return Person.sync({ force: true })
.then(() => {
const inserts = [
{ systemId: 1, system: 'system1', name: 'Alice' }
];
return Person.bulkCreate(inserts);
})
.then(people => {
expect(people.length).to.equal(1);
expect(people[0].systemId).to.equal(1);
expect(people[0].system).to.equal('system1');
expect(people[0].name).to.equal('Alice');

const updates = [
{ systemId: 1, system: 'system1', name: 'CHANGED NAME' },
{ systemId: 1, system: 'system2', name: 'Bob' }
];

return Person.bulkCreate(updates, { updateOnDuplicate: ['systemId', 'system', 'name'] });
})
.then(people => {
expect(people.length).to.equal(2);
expect(people[0].systemId).to.equal(1);
expect(people[0].system).to.equal('system1');
expect(people[0].name).to.equal('CHANGED NAME');
expect(people[1].systemId).to.equal(1);
expect(people[1].system).to.equal('system2');
expect(people[1].name).to.equal('Bob');
});
});

it('when the primary key column names and model field names are different and have composite unique constraints', function() {
const Person = this.sequelize.define('Person', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
field: 'id'
},
systemId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: 'system_id_system_unique',
field: 'system_id'
},
system: {
type: DataTypes.STRING,
allowNull: false,
unique: 'system_id_system_unique',
field: 'system'
},
name: {
type: DataTypes.STRING,
allowNull: false,
field: 'name'
}
}, {});

return Person.sync({ force: true })
.then(() => {
const inserts = [
{ id: 1, systemId: 1, system: 'system1', name: 'Alice' }
];
return Person.bulkCreate(inserts);
})
.then(people => {
expect(people.length).to.equal(1);
expect(people[0].systemId).to.equal(1);
expect(people[0].system).to.equal('system1');
expect(people[0].name).to.equal('Alice');

const updates = [
{ id: 1, systemId: 1, system: 'system1', name: 'CHANGED NAME' },
{ id: 2, systemId: 1, system: 'system2', name: 'Bob' }
];

return Person.bulkCreate(updates, { updateOnDuplicate: ['systemId', 'system', 'name'] });
})
.then(people => {
expect(people.length).to.equal(2);
expect(people[0].systemId).to.equal(1);
expect(people[0].system).to.equal('system1');
expect(people[0].name).to.equal('CHANGED NAME');
expect(people[1].systemId).to.equal(1);
expect(people[1].system).to.equal('system2');
expect(people[1].name).to.equal('Bob');
});
});

});


Expand Down

0 comments on commit 5e92d8b

Please sign in to comment.