MCPcopy
hub / github.com/sequelize/sequelize / upsert

Method upsert

lib/model.js:2462–2529  ·  view source on GitHub ↗

* Insert or update a single row. An update will be executed if a row which matches the supplied values on either the primary key or a unique key is found. Note that the unique index must be defined in your sequelize model and not just in the table. Otherwise you may experience a unique constraint vi

(values, options)

Source from the content-addressed store, hash-verified

2460 * @returns {Promise<Array<Model, boolean | null>>} returns an array with two elements, the first being the new record and the second being `true` if it was just created or `false` if it already existed (except on Postgres and SQLite, which can't detect this and will always return `null` instead of a boolean).
2461 */
2462 static async upsert(values, options) {
2463 options = {
2464 hooks: true,
2465 returning: true,
2466 validate: true,
2467 ...Utils.cloneDeep(options)
2468 };
2469
2470 const createdAtAttr = this._timestampAttributes.createdAt;
2471 const updatedAtAttr = this._timestampAttributes.updatedAt;
2472 const hasPrimary = this.primaryKeyField in values || this.primaryKeyAttribute in values;
2473 const instance = this.build(values);
2474
2475 options.model = this;
2476 options.instance = instance;
2477
2478 const changed = Array.from(instance._changed);
2479 if (!options.fields) {
2480 options.fields = changed;
2481 }
2482
2483 if (options.validate) {
2484 await instance.validate(options);
2485 }
2486 // Map field names
2487 const updatedDataValues = _.pick(instance.dataValues, changed);
2488 const insertValues = Utils.mapValueFieldNames(instance.dataValues, Object.keys(instance.rawAttributes), this);
2489 const updateValues = Utils.mapValueFieldNames(updatedDataValues, options.fields, this);
2490 const now = Utils.now(this.sequelize.options.dialect);
2491
2492 // Attach createdAt
2493 if (createdAtAttr && !insertValues[createdAtAttr]) {
2494 const field = this.rawAttributes[createdAtAttr].field || createdAtAttr;
2495 insertValues[field] = this._getDefaultTimestamp(createdAtAttr) || now;
2496 }
2497 if (updatedAtAttr && !insertValues[updatedAtAttr]) {
2498 const field = this.rawAttributes[updatedAtAttr].field || updatedAtAttr;
2499 insertValues[field] = updateValues[field] = this._getDefaultTimestamp(updatedAtAttr) || now;
2500 }
2501
2502 // Db2 does not allow NULL values for unique columns.
2503 // Add dummy values if not provided by test case or user.
2504 if (this.sequelize.options.dialect === 'db2') {
2505 this.uniqno = this.sequelize.dialect.queryGenerator.addUniqueFields(
2506 insertValues, this.rawAttributes, this.uniqno);
2507 }
2508
2509 // Build adds a null value for the primary key, if none was given by the user.
2510 // We need to remove that because of some Postgres technicalities.
2511 if (!hasPrimary && this.primaryKeyAttribute && !this.rawAttributes[this.primaryKeyAttribute].defaultValue) {
2512 delete insertValues[this.primaryKeyField];
2513 delete updateValues[this.primaryKeyField];
2514 }
2515
2516 if (options.hooks) {
2517 await this.runHooks('beforeUpsert', values, options);
2518 }
2519 const result = await this.queryInterface.upsert(this.getTableName(options), insertValues, updateValues, instance.where(), options);

Callers 5

testFunction · 0.45
instance.test.jsFile · 0.45
upsert.test.jsFile · 0.45
upsert.test.jsFile · 0.45
upsert.test.jsFile · 0.45

Calls 6

buildMethod · 0.95
_getDefaultTimestampMethod · 0.95
getTableNameMethod · 0.95
addUniqueFieldsMethod · 0.80
validateMethod · 0.65
whereMethod · 0.45

Tested by 1

testFunction · 0.36