不要怂,就是干,撸起袖子干!

Commit 6dcb565e by Pedro Augusto de Paula Barbosa Committed by GitHub

fix(bulk-create): `ON CONFLICT` with unique index (#13345)

Co-authored-by: Brian Schardt <35744893+brianschardt@users.noreply.github.com>
Co-authored-by: AllAwesome497 <47748690+AllAwesome497@users.noreply.github.com>
1 parent 97b3767f
......@@ -2683,11 +2683,24 @@ class Model {
// Map updateOnDuplicate attributes to fields
if (options.updateOnDuplicate) {
options.updateOnDuplicate = options.updateOnDuplicate.map(attr => model.rawAttributes[attr].field || attr);
// 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).reduce(c => c[0]).value();
const upsertKeys = [];
for (const i of model._indexes) {
if (i.unique && !i.where) { // Don't infer partial indexes
upsertKeys.push(...i.fields);
}
}
const firstUniqueKey = Object.values(model.uniqueKeys).find(c => c.fields.length >= 1);
if (firstUniqueKey && firstUniqueKey.fields) {
upsertKeys.push(...firstUniqueKey.fields);
}
options.upsertKeys = upsertKeys.length > 0
? upsertKeys
: Object.values(model.primaryKeys).map(x => x.field);
}
// Map returning attributes to fields
......
......@@ -638,6 +638,67 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(people[1].name).to.equal('Bob');
});
it('[#12516] when the primary key column names and model field names are different and have composite unique index constraints', async function() {
const Person = this.sequelize.define(
'Person',
{
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
field: 'id'
},
systemId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'system_id'
},
system: {
type: DataTypes.STRING,
allowNull: false,
field: 'system'
},
name: {
type: DataTypes.STRING,
allowNull: false,
field: 'name'
}
},
{
indexes: [
{
unique: true,
fields: ['system_id', 'system']
}
]
}
);
await Person.sync({ force: true });
const inserts = [{ systemId: 1, system: 'system1', name: 'Alice' }];
const people0 = await Person.bulkCreate(inserts);
expect(people0.length).to.equal(1);
expect(people0[0].systemId).to.equal(1);
expect(people0[0].system).to.equal('system1');
expect(people0[0].name).to.equal('Alice');
const updates = [
{ systemId: 1, system: 'system1', name: 'CHANGED NAME' },
{ systemId: 1, system: 'system2', name: 'Bob' }
];
const people = await Person.bulkCreate(updates, {
updateOnDuplicate: ['systemId', 'system', 'name']
});
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');
});
});
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!