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

Commit bca3640b by Sushant Committed by Jan Aagaard Meier

Fixes bulkCreate, Now it properly maps fields to attributes (#6219)

* map the fieldname to attribute names

* Added timestamp attributes to fields list

* use the field to generate attributes list

* check there are no fields in dataValues
1 parent 0fe72de0
......@@ -25,6 +25,7 @@
- [FIXED] `upsert` does not fail anymore on not null validations [#5711](https://github.com/sequelize/sequelize/issues/5711)
- [FIXED] Don't remove includes from count queries and unify findAndCount and count queries. [#6123](https://github.com/sequelize/sequelize/issues/6123)
- [FIXED] `Model.count` with `options.col` and `options.include` works properly now
- [FIXED] `bulkCreate` don't map fields to attributes properly [#4476](https://github.com/sequelize/sequelize/issues/4476)[#3908](https://github.com/sequelize/sequelize/issues/3908)[#4103](https://github.com/sequelize/sequelize/issues/4103)[#3764](https://github.com/sequelize/sequelize/issues/3764)[#3789](https://github.com/sequelize/sequelize/issues/3789)[#4600](https://github.com/sequelize/sequelize/issues/4600)
## BC breaks:
- Range type bounds now default to [postgres default](https://www.postgresql.org/docs/9.5/static/rangetypes.html#RANGETYPES-CONSTRUCT) `[)` (inclusive, exclusive), previously was `()` (exclusive, exclusive)
......
......@@ -2063,18 +2063,21 @@ class Model {
});
}
}).then(() => {
/* jshint -W030 */
for (const instance of instances) {
const values = Utils.mapValueFieldNames(instance.dataValues, options.fields, this);
let values = instance.dataValues;
// set createdAt/updatedAt attributes
if (createdAtAttr && !values[createdAtAttr]) {
values[createdAtAttr] = now;
options.fields.indexOf(createdAtAttr) === -1 && options.fields.push(createdAtAttr);
}
if (updatedAtAttr && !values[updatedAtAttr]) {
values[updatedAtAttr] = now;
options.fields.indexOf(updatedAtAttr) === -1 && options.fields.push(updatedAtAttr);
}
instance.dataValues = values;
instance.dataValues = Utils.mapValueFieldNames(values, options.fields, this);
}
if (options.individualHooks) {
......@@ -2101,10 +2104,7 @@ class Model {
// Map attributes for serial identification
const attributes = {};
for (const attr in this.tableAttributes) {
attributes[attr] = this.rawAttributes[attr];
if (this.rawAttributes[attr].field) {
attributes[this.rawAttributes[attr].field] = this.rawAttributes[attr];
}
attributes[this.rawAttributes[attr].field] = this.rawAttributes[attr];
}
return this.QueryInterface.bulkInsert(this.getTableName(options), records, options, attributes).then(results => {
......@@ -2118,6 +2118,20 @@ class Model {
});
}
}).then(() => {
// map fields back to attributes
instances.forEach((instance) => {
for (const attr in this.rawAttributes) {
if (this.rawAttributes[attr].field &&
instance.dataValues[this.rawAttributes[attr].field] !== undefined &&
this.rawAttributes[attr].field !== attr
) {
instance.set(attr, instance.dataValues[this.rawAttributes[attr].field]);
delete instance.dataValues[this.rawAttributes[attr].field];
}
}
});
// Run after hook
if (options.hooks) {
return this.runHooks('afterBulkCreate', instances, options);
......
......@@ -1808,6 +1808,50 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
});
it('should properly map field names to attribute names', function() {
var Maya = this.sequelize.define('Maya', {
name: Sequelize.STRING,
secret: {
field: 'secret_given',
type: Sequelize.STRING
},
createdAt: {
field: 'created_at',
type: Sequelize.DATE
},
updatedAt: {
field: 'updated_at',
type: Sequelize.DATE
}
});
var M1 = { id: 1, name: 'Prathma Maya', secret: 'You are on list #1'};
var M2 = { id: 2, name: 'Dwitiya Maya', secret: 'You are on list #2'};
return Maya.sync({ force: true }).then(() => Maya.create(M1))
.then((m) => {
expect(m.createdAt).to.be.ok;
expect(m.id).to.be.eql(M1.id);
expect(m.name).to.be.eql(M1.name);
expect(m.secret).to.be.eql(M1.secret);
return Maya.bulkCreate([M2]);
}).spread((m) => {
// only attributes are returned, no fields are mixed
expect(m.createdAt).to.be.ok;
expect(m.created_at).to.not.exist;
expect(m.secret_given).to.not.exist;
expect(m.get('secret_given')).not.to.be.defined;
expect(m.get('created_at')).not.to.be.defined;
// values look fine
expect(m.id).to.be.eql(M2.id);
expect(m.name).to.be.eql(M2.name);
expect(m.secret).to.be.eql(M2.secret);
});
});
});
it('should support logging', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!